Java如何实现和设计一个抽象类

时间:2013-11-01 17:29:50

标签: java abstract protected

我在java代码中遇到了设计问题。我的应用程序使用导弹,并且有不同类型的导弹,除了具有3个独特属性外,所有导弹都相同。导弹的构造者必须知道这些属性。我决定使导弹成为一个抽象类,但是我不能将值赋给方法/构造函数之外的子类中的受保护变量。另外我不能在构造函数中声明变量,因为我必须首先调用超构造函数。 我怎么能对这个问题很聪明?

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;
}
}

除了它不起作用外,还有一个理想的子类实现。 (它无法识别受保护的变量)。我该怎么办?

public class Laser extends Missile {

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

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

}

4 个答案:

答案 0 :(得分:3)

我认为做你想要它做的事情的最好方法是在Missile中创建子类必须实现的抽象方法。例如,将这些添加到导弹:

public abstract int getMissileSpeed();
public abstract int getMissileHeight();
public abstract int getFileName();

然后你的子类必须实现它,你可以使它保持不变:

public class Laser extends Missile {

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

    public int getMissileSpeed() {
        return 2;
    }

    public int getMissileHeight() {
        return 5;
    }

    public String getFileName() {
        return "laser.jpg";
    }

}

编辑:然后当然要在任何想要检索常量值的地方调用这些方法。

答案 1 :(得分:3)

将基类字段和构造函数更改为

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);
}

子类:

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

    ...
}

属性已经在基类中,因此不能在子类中重新定义它们。全大写命名保留给Java中的常量。

答案 2 :(得分:1)

我不确定导弹是否需要是一个抽象类,但我认为这样的事情可能就是你想要的:

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;

    public Missile(int x, int y, int speed, int height, String file) {
        MISSILE_SPEED = speed;
        MISSILE_HEIGHT = height;

        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 class Laser extends Missile {

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

}

答案 3 :(得分:0)

创建一个界面并将所有最终字段放入其中。 现在在Missile和Laser中实现这个接口。至少可以解决访问问题。