Results 1 to 13 of 13
  1. #1
    CyJackX is offline Member
    Join Date
    Mar 2010
    Posts
    9
    Rep Power
    0

    Default 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.

  2. #2
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    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-

  3. #3
    CyJackX is offline Member
    Join Date
    Mar 2010
    Posts
    9
    Rep Power
    0

    Default

    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.

  4. #4
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    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-

  5. #5
    CyJackX is offline Member
    Join Date
    Mar 2010
    Posts
    9
    Rep Power
    0

    Default

    Quote Originally Posted by gcalvin View Post
    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-
    I suppose not...so should each subclass define it themselves? Even though it is a repetition of the same code with one variable tweaked?

    Or, by "don't do that," do you mean I should find a different design structure altogether?

  6. #6
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    I think you can implement a getter method in the superclass that relies on subclass instance variables, right?

    Java Code:
            public double getVelocity() {
                return getShipSpeed() + getShotSpeed();
            }
    
            public double getShipSpeed() {
                return this.shipSpeed;
            }
    
            public double getShotSpeed() {
                return this.shotSpeed;
            }
    Or am I missing something?

    -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.

  7. #7
    CyJackX is offline Member
    Join Date
    Mar 2010
    Posts
    9
    Rep Power
    0

    Default

    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.

  8. #8
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    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-

  9. #9
    gcalvin is offline Senior Member
    Join Date
    Mar 2010
    Posts
    953
    Rep Power
    5

    Default

    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.

    Java Code:
            Shot s = new LaserShot();
            s.fire();
    But if I'm wrong, somebody else will have to take it from here. :)

    -Gary-

  10. #10
    CyJackX is offline Member
    Join Date
    Mar 2010
    Posts
    9
    Rep Power
    0

    Default

    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.

  11. #11
    CyJackX is offline Member
    Join Date
    Mar 2010
    Posts
    9
    Rep Power
    0

    Default

    Mm, morning. Any ideas, folks?

  12. #12
    iluxa is offline Senior Member
    Join Date
    Mar 2010
    Posts
    266
    Rep Power
    5

    Default

    Here's how you do it: don't use an instance variable. Use a method instead.

    For example:

    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 ();
      }
    }
    and implementation:

    Java Code:
    class ConcreteRectangle extends Rectangle {
      protected double getWidth () {
        return 5;
      }
      protected double getHeight () {
        return 4;
      }
    }
    The benefits you get from this approach:
    - you can never "forget" to initialize the variable
    - you can stick functionality into the abstract class that depends on implementation of the sub-classes

  13. #13
    CyJackX is offline Member
    Join Date
    Mar 2010
    Posts
    9
    Rep Power
    0

    Default

    Quote Originally Posted by iluxa View Post
    Here's how you do it: don't use an instance variable. Use a method instead.
    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

  1. Replies: 8
    Last Post: 04-16-2012, 11:00 PM
  2. What are Instance variables and static variables?
    By sandeshforu in forum New To Java
    Replies: 3
    Last Post: 09-09-2009, 05:48 PM
  3. accessing instance variables from static methods
    By ravian in forum New To Java
    Replies: 7
    Last Post: 03-01-2009, 10:09 PM
  4. static are instance variables
    By gabri in forum Advanced Java
    Replies: 12
    Last Post: 09-30-2008, 06:30 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •