0

我在我的 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

4 回答 4

4

我认为做你想做的最好的方法是在 Missile 中创建子类必须实现的抽象方法。例如,将这些添加到 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";
    }

}

编辑:当然,在任何你想检索常量值的地方,你只需调用这些方法。

于 2013-11-01T17:37:33.313 回答
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 中的常量。

于 2013-11-01T17:38:27.803 回答
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");
    }

}
于 2013-11-01T17:39:51.960 回答
0

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

于 2013-11-01T17:44:01.643 回答