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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19732034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 19:47:20  来源:igfitidea点击:

Java how to implement and design an abstract class

javaabstractprotected

提问by user2651804

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?

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

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

}

}

采纳答案by JB Nizet

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 中的常量。

回答by trevor-e

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. For example, add these to Missile:

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

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

回答by Darius Makaitis

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

}

回答by Ashish

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.

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