例如,让我们从游戏中说:
public class Enemy {
protected int x, y;
protected int width, height;
protected int hitpoints;
protected int speed;
}
我希望有多个类扩展这个类(每个敌人类型一个),但我需要确保(最好强制这个)扩展类将值赋给这些变量的所有。
我不想通过构造函数调用传递它们或将它们设置在其中 - 所以目前我不得不通过简单地将整个减速度复制到每个类并在同一行中为它们赋值来实现这一点。
是否有更有效的方法可以做到这一点? (对不起,如果问题有些模糊......)
提前致谢。
编辑 - 这是我创建扩展类的方法:
public class Skeleton extends Enemy {
protected int x, y;
protected int width, height;
protected int hitpoints;
protected int speed;
}
答案 0 :(得分:4)
Jordão答案的另一种选择是使用builder pattern:
public class SkeletonBuilder
{
private int x, y, width, height...;
public SkeletonBuilder withCoords(int x, int y) { this.x = x; this.y = y; }
public SkeletonBuilder withSize(int width, int height) { this.width = width; this.height = height; }
...
public Skeleton build() { return new Skeleton(x, y, width, height); }
}
public class Skeleton
{
/* package */ Skeleton(int x, int y, int width, int height, ...)
}
// game code
Skeleton skeleton = new SkeletonBuilder().withCoords(1, 4).withSize(2, 30).build();
如果某些参数可以默认,那么在SkeletonBuilder
构造函数中设置它们。如果需要其他参数,那么您可以在构建器中设置boolean
标志,或使用盒装对象,如果未设置,则在build()
方法中失败。
答案 1 :(得分:1)
要强制子类在构造函数和中设置值以使构造函数调用可读,您将不得不编写更多代码超类。这是我可以考虑的一种方式(只显示x
和y
):
abstract class Enemy {
protected int x, y;
protected Enemy(X x, Y y) {
this.x = x.value;
this.y = y.value;
}
protected static class X {
private final int value;
private X(int value) { this.value = value; }
}
protected static class Y {
private final int value;
private Y(int value) { this.value = value; }
}
protected static X x(int value) { return new X(value); }
protected static Y y(int value) { return new Y(value); }
}
class Skeleton extends Enemy {
public Skeleton() {
super(x(12), y(13));
}
}
UPDATE :如果使用封装相关值的复合类型是有意义的,它们可以使代码更好:
class Skeleton extends Enemy {
public Skeleton() {
super(position(12, 13), size(300, 300), ...);
}
}
答案 2 :(得分:0)
你的类Skeleton不应该声明与Enemy中设置的相同的变量。
关于你的问题,最简单的选择是创建变量final
,然后在构造函数中设置它们。编译器将强制它们都已设置。
答案 3 :(得分:0)
我认为您应该创建一个Type接口
interface Type
{
int getX();
int getY();
int getWidth() ;
int getHeight();
int getHitpoints();
int getSpeed();
}
然后编译器将执行执行工作。
答案 4 :(得分:-1)
根据注释(虽然我会使用超类上的构造函数),一种方法是将Enemy类声明为抽象(如果你只是想在那里定义常见行为,那可能就是这样)并将变量初始化为对抽象方法的调用。 这样,扩展类将被强制实现这些方法,实质上是初始化变量。
这是一个简化的例子:
public abstract class Enemy {
protected int x = getX();
protected int y = getY();
protected abstract int getX();
protected abstract int getY();
}
public class Skeleton extends Enemy {
@Override
protected int getX() { return 10; }
@Override
protected int getY() { return 10; }
}
它更冗长,但也许它实现了您正在寻找的可读性。