Search code examples
javaabstractprotected

Java how to implement and design an abstract class


I've run into a design problem in my java code. My application uses missiles, and there are different types of missiles that all work identical except they have 3 unique attributes. The constructor of a missile must know these attributes. I decided to make missile an abstract class, but I can't assign values to protected variables in a subclass outside of a method/constructor. Also I can't declare the variables in the constructor, because I must make the call to the super-constructor first thing. How can I be smart about this problem?

public abstract class Missile {

private int x, y;
private Image image;
boolean visible;

private final int BOARD_WIDTH = 390;

protected final int MISSILE_SPEED;
protected final int MISSILE_HEIGHT;
protected String file;

public Missile(int x, int y) {
    ImageIcon ii =
        new ImageIcon(this.getClass().getResource(file));
    image = ii.getImage();
    visible = true;
    this.x = x;
    this.y = y - Math.floor(MISSILE_HEIGHT/2);
}


public Image getImage() {
    return image;
}

public int getX() {
    return x;
}

public int getY() {
    return y;
}

public boolean isVisible() {
    return visible;
}

public void move() {
    x += MISSILE_SPEED;
    if (x > BOARD_WIDTH)
        visible = false;
}
}

And there is an ideal implementation of a subclass, except it doesn't work. (it can't recognize the protected variables). What do I do?

public class Laser extends Missile {

    MISSILE_SPEED = 2;
    MISSILE_HEIGHT = 5;
    file = "laser.jpg";

public Laser(int x, int y) {
    super(x, y);
}

}


Solution

  • Change the base class fields and constructors to

    protected final int speed;
    protected final int height;
    
    public Missile(int x, int y, int speed, int height, String file) {
        ImageIcon ii =
            new ImageIcon(this.getClass().getResource(file));
        image = ii.getImage();
        visible = true;
        this.speed = speed;
        this.height = height;
        this.x = x;
        this.y = y - Math.floor(height/2);
    }
    

    And the subclass to:

    public class Laser extends Missile {
        public Laser(int x, int y) {
            super(x, y, 2, 5, "laser.jpg");
        }
    
        ...
    }
    

    The attributes are already in the base class, so they must not be redefined in the subclass. All-uppercase naming is reserved to constants in Java.