这是我的情况
public abstract class Actions {
public static Actions STAND;
public static Actions ATTACK;
public static Actions COLONIZE;
public static Actions DEFEND;
public static Actions TURN_CW;
public static Actions TURN_CCW;
public static Actions DIE;
public abstract long[] getFramesDurations();
public abstract int[] getBaseTiles();
}
public class SimpleActions extends Actions{
public static Actions STAND = new SimpleActions( new long[]{120,120,120,120,120,120,120}, new int[]{0,1,2,3,4,5,6});
public static Actions ATTACK = new SimpleActions( new long[]{120,120,120,120,120,120,120,120,120}, new int[]{7,8,9,10,11,12,13,14,15});
public static Actions COLONIZE = new SimpleActions( new long[]{120,120,120,120,120,120,120}, new int[]{7,8,9,10,11,12,13,14,15});
public static Actions DEFEND = new SimpleActions(new long[]{1}, new int[]{1});
public static Actions TURN_CW = new SimpleActions( new long[]{1}, new int[]{1});
public static Actions TURN_CCW = new SimpleActions( new long[]{1}, new int[]{1});
public static Actions DIE = new SimpleActions( new long[]{1}, new int[]{1});
private final long[] mActionFramesDurations;
private final int[] mActionBaseTiles;
SimpleActions(long[] pActionFramesDurations, int[] pActionBaseTiles) {
mActionFramesDurations = pActionFramesDurations;
mActionBaseTiles = pActionBaseTiles;
}
public long[] getFramesDurations()
{
return mActionFramesDurations;
}
public int[] getBaseTiles()
{
return mActionBaseTiles;
}
}
public abstract class A<T extends Actions> {
A() {
doSomething(T.STAND);
}
protected void doSomething(Actions action) { use action somewhere}
}
public class B extends A<SimpleActions> {
B() {
super();
}
}
当A的构造函数调用doSomething时,因为操作为null,所以我总是会得到nullPointerException。
由于B扩展了A,所以我期望它使用SimpleActions.STAND,而不是Actions.STAND。
我究竟做错了什么?我应该怎么做?
最佳答案
Java语言规范writes:
边界为T&I1 ... In的类型变量X的成员是交集类型(§4.9)T&I1 ... In的成员,出现在声明类型变量的点。
这就是为什么表达式T.STAND
引用Actions.STAND
而不是SimpleActions.STAND
的原因。Actions.STAND
和SimpleActions.STAND
是不同的字段(与非静态方法不同,不能覆盖这些字段。)
这已经突出了委派给子类的一种方法:定义子类必须重写的访问器方法(getter):
abstract class Actions {
abstract Actions stand();
}
class SimpleActions extends Actions {
private static final Actions STAND = ...;
@Override Actions stand() { return STAND;}
}
并调用
t.stand();
其中t是在构造时提供给
A
的T的实例。或者也许将此方法移到其他类型(MotionRegistry
?)中,并在构造A
时提供该方法的实例。也就是说,您的设计看起来非常复杂,我无法撼动您的代码可以简化的感觉(如果Actions和SimpleActions都描述相同的动作,您是否需要区分它们?)