这是我的情况

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.STANDSimpleActions.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都描述相同的动作,您是否需要区分它们?)

07-28 06:54