我在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);
}
}
答案 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中实现这个接口。至少可以解决访问问题。