Results 1 to 13 of 13
- 03-16-2010, 04:29 AM #1
Member
- Join Date
- Mar 2010
- Posts
- 9
- Rep Power
- 0
OOP/RTII: Abstract classes with methods using uninitialized instance variables?
These are my questions in general:
Say an abstract class defines an instant variable, but does not initialize it, and then defines a method that uses that variable.
The reason that variable is not defined is that I want all subclasses to use the same method, but with their own version of that variable.
The variable should remain the same amongst all members of a given subclass, but I don't think it should be static, because that would make ALL members of the abstract superclass have the same variable, right?
From what I've gleaned from various sources, I feel that the answer lies in learning how to use class literals, instanceof, and such, but I'm not sure right now.
In more specific details:
There is an abstract superclass called Shot. A ship in the game will shoot out Shots, but there are specialized versions of these Shots, say LaserShot and PlasmaShot. Now, each shot has its own special properties such as shotDelay(The minimum time between shots), or shotSpeed(The initial velocity of said shot).
There is a method defined in class Shot that returns a boolean based on whether or not enough time has elapsed since the last shot (using shotDelay).
What is the best way to initialize these variables? In the constructor of the subclasses?
Second, the shotSpeed is used in the constructor of the abstract superclass, Shot. Basically each Shot object is an object in space, with an x,y,mass,radius,velocityX,velocityY, etc. The Velocity of each shot is based on the velocity of the ship that is shooting it, PLUS the shot's shotSpeed. However, the catch-22 that I can't figure out (elegantly, at least), comes here. Since LaserShot (or PlasmaShot) defines shotSpeed, initializing either requires a call to the superclass constructor first. But since the shotSpeed is not defined in the superclass, it can't construct, because it needs to construct the subclass to define it! Is this the flaw of poor design, or is there a tool I am not using? This is not the first issue of its kind I have encountered, but I have gotten tired of odd loop-arounds using initialization blocks and such.
- 03-16-2010, 04:38 AM #2
Senior Member
- Join Date
- Mar 2010
- Posts
- 953
- Rep Power
- 4
Why not initialize it to some value (maybe 0?) in the superclass, and then override that value in the subclass constructor? You would need to set the instance variable to protected rather than private in the superclass, but is that going to be a problem?
-Gary-
- 03-16-2010, 04:41 AM #3
Member
- Join Date
- Mar 2010
- Posts
- 9
- Rep Power
- 0
I have been trying something like that, but doesn't that mean that I'll need to override that value in the constructor of EVERY subclass? That's why I'm looking for the way to get it done in the superclass.
- 03-16-2010, 04:42 AM #4
Senior Member
- Join Date
- Mar 2010
- Posts
- 953
- Rep Power
- 4
Sorry, I see what you're saying -- you're wanting to set up Velocity in the superclass constructor, but you can't do that without knowing shotSpeed. I think the answer is "don't do that".
Think of it this way -- if you had an abstract class Cat with subclasses Tiger and Lynx, would it make any sense to try to set tailLength in the Cat constructor?
-Gary-
- 03-16-2010, 04:46 AM #5
Member
- Join Date
- Mar 2010
- Posts
- 9
- Rep Power
- 0
- 03-16-2010, 04:47 AM #6
Senior Member
- Join Date
- Mar 2010
- Posts
- 953
- Rep Power
- 4
I think you can implement a getter method in the superclass that relies on subclass instance variables, right?
Or am I missing something?Java Code:public double getVelocity() { return getShipSpeed() + getShotSpeed(); } public double getShipSpeed() { return this.shipSpeed; } public double getShotSpeed() { return this.shotSpeed; }
-Gary-
EDIT: That's not quite right, as a Shot subclass wouldn't have a shipSpeed instance variable, but you get the idea.Last edited by gcalvin; 03-16-2010 at 04:53 AM.
- 03-16-2010, 04:54 AM #7
Member
- Join Date
- Mar 2010
- Posts
- 9
- Rep Power
- 0
When/where would I call these methods?
If I call them in the constructor of the superclass, none of the variables will have been initialized yet.
- 03-16-2010, 04:57 AM #8
Senior Member
- Join Date
- Mar 2010
- Posts
- 953
- Rep Power
- 4
Well, the whole idea of an abstract class is that it never gets instantiated directly anyway. You call the methods when you need the values -- that wouldn't be in a Shot constructor, would it? I have to leave where I am now, but maybe if you can share more of your code, somebody else will have something constructive to offer.
-Gary-
- 03-16-2010, 05:01 AM #9
Senior Member
- Join Date
- Mar 2010
- Posts
- 953
- Rep Power
- 4
Sorry, I think I see where your thinking is now -- you basically want to create a new SomeKindOfShot() and have it just go. I think you can get just about all of what you want by just implementing a fire() method in the Shot superclass.
But if I'm wrong, somebody else will have to take it from here. :)Java Code:Shot s = new LaserShot(); s.fire();
-Gary-
- 03-16-2010, 05:14 AM #10
Member
- Join Date
- Mar 2010
- Posts
- 9
- Rep Power
- 0
Thanks for the help, anyway.
The trouble is that the superconstructor uses the uninitialized shotSpeed of the subclass to determine its initial velocity. Why have a constructor for an abstract class? I just wanted to make sure that all subclasses would follow the same form of initialization.
- 03-16-2010, 03:20 PM #11
Member
- Join Date
- Mar 2010
- Posts
- 9
- Rep Power
- 0
Mm, morning. Any ideas, folks?
- 03-16-2010, 05:35 PM #12
Senior Member
- Join Date
- Mar 2010
- Posts
- 266
- Rep Power
- 4
Here's how you do it: don't use an instance variable. Use a method instead.
For example:
and implementation:Java Code:abstract class Rectangle { protected abstract double getWidth (); // must be overridden!!! protected abstract double getHeight (); // must be overridden!!! public double getArea () { return getWidth () * getHeight (); } }
The benefits you get from this approach:Java Code:class ConcreteRectangle extends Rectangle { protected double getWidth () { return 5; } protected double getHeight () { return 4; } }
- you can never "forget" to initialize the variable
- you can stick functionality into the abstract class that depends on implementation of the sub-classes
- 03-16-2010, 06:45 PM #13
Member
- Join Date
- Mar 2010
- Posts
- 9
- Rep Power
- 0
Alright, I've implemented that idea, which has reduced my code by a line, but I still wanted to see if I were able to use one of those methods in the superconstructor, which I can't, because that's a reference to "this" before the constructor has finished. It's still helped me in a workaround, though.
Similar Threads
-
Trouble with static methods and boolean equals() methods with classes
By dreamingofgreen in forum New To JavaReplies: 8Last Post: 04-16-2012, 11:00 PM -
What are Instance variables and static variables?
By sandeshforu in forum New To JavaReplies: 3Last Post: 09-09-2009, 05:48 PM -
accessing instance variables from static methods
By ravian in forum New To JavaReplies: 7Last Post: 03-01-2009, 10:09 PM -
static are instance variables
By gabri in forum Advanced JavaReplies: 12Last Post: 09-30-2008, 06:30 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks