简体   繁体   English

Java如何实现和设计抽象类

[英]Java how to implement and design an abstract class

I've run into a design problem in my java code. 我在Java代码中遇到了一个设计问题。 My application uses missiles, and there are different types of missiles that all work identical except they have 3 unique attributes. 我的应用程序使用导弹,除了具有3个独特属性外,其他所有类型的导弹工作原理相同。 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);
}

} }

I think the best way to do what you want it to do is make abstract methods in Missile that the subclasses have to implement. 我认为做您想要做的最好的方法是在Missile中创建子类必须实现的抽象方法。 For example, add these to Missile: 例如,将它们添加到导弹中:

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

Then your subclass has to implement it, and you can make it constant like so: 然后,您的子类必须实现它,并且可以像下面这样使其保持不变:

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

}

edit: And then of course anywhere that you want to retrieve the constant value you just call those methods. 编辑:然后,当然,您要检索常量值的任何地方都可以调用这些方法。

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. 全大写命名保留给Java中的常量。

I'm not sure if missile needs to be an abstract class, but I think something like this might be what you're going for: 我不确定导弹是否需要成为抽象类,但是我想您可能想要的是这样的东西:

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

}

Create an interface and put all your final fields in it. 创建一个接口,并将所有最终字段放入其中。 Now implement this interface within Missile and Laser both. 现在在“导弹”和“激光”中都实现此接口。 At least that would solve the issue of access. 至少那将解决访问问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM