我正在尝试通过蚂蚁将其作为泛型实现一个抽象超类Race
,以便为蚂蚁访问诸如“ Movement Speed”之类的属性。对于不同的种族,我将创建扩展Race
的类,并且显然我想为每个Race
提供不同的属性。 “运动速度”必须以某种方式在Race
中是静态的,因此我可以通过Class而不是对象的实例来访问它们,但是它不能是静态的,因为对于所有种族而言,它都是相同的。我需要一种解决此问题的方法,因为我的整个程序结构都依赖于此。
我不能使Race
成为Ant
的超类,因为我有Ant
的子类,如Drone
或Queen
,并且所有种族都应该可以使用它们。
public abstract class Race {
public static double speed;
}
public class defaultAnt extends Race {
public static double speed = 2;
}
public abstract class Ant<R extends Race> {
public void move(){
speed = R.speed;
}
}
当我这样尝试时,在所有比赛中都一样,尽管不应该这样。
最佳答案
在某种程度上,“运动速度”在Race中必须是静态的,因此我可以按班级访问它们
一点也不。在良好的OOP设计中,尤其是在Java中,将static
视为异常。 OOP方法将是这样的:
public abstract class Race {
protected abstract double getIndividualSpeed();
...
然后子类化(在正确的位置)@Override,以提供单独的速度。
但是如前所述:这里的关键是您退后一步,重新思考您的设计。使用静态字段,尤其是在“多态”上下文中,几乎是不行的。
除此之外,关于泛型的想法在这里不太适合。泛型(或多或少)关于“包含”某物。当您说
class Foo<T extends Bar>
时,您便表示Foo实例将以某种方式拥有/关联到Bar类。是的,以某种方式适合您的用例,但是(个人),我不确定泛型是否是此处的正确选择。事实是:泛型通常是编译时的事情。在运行时,
R
的概念消失了。您的班级Ant
不知道您是否有Ant<Drone> ant = new Ant...
要么
Ant<Queen> a2 = ...
换句话说:
R.speed
从概念上讲是不可能的。更加面向对象的方法如下所示:public abstract class BaseAnt<R extends Race> {
protected final R rInstance;
protected BaseAnt(R rInstance) { this.R rInstance = R rInstance; }
public final double move(double distance) {
return distance / Instance.getSpeed();
}
public class Ant<R extends Race> {
ctor that calls super constructor
然后
public enum Race {
DRONE(5), QUEEN(1);
private final double speed;
private Race(double speed) { this.speed = speed; }
public double getSpeed() { return speed; }
换句话说:您可以使用充当“常量提供者”的枚举。您可以在Race.DRONE上调用
getSpeed()
;然后您返回5
。然后,您可以使用Race.DRONE或Race.QUEEN实例化Ant。
另一方面,BaseAnt类对Ants执行所有“常见”的操作,然后您的子类添加特定的行为。
关于java - 抽象父类(super class)中静态变量的替代方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57945690/