Java - 参考实施 class

Java - refer to implemented class

我有一个小问题:我为我的游戏开发了一个 "ExampleQuest" class,它扩展了抽象的 class 任务。我这样做是为了创建个人任务 classes。现在我的 ExampleQuest class 应该计算我的实体的死亡,所以我实现了我的 EntityListener。现在我必须在我的 Playstate class 中注册它以使一切正常,但这是我的实际问题:方法 Playstate.addEntityListener(this) 给了我一个空指针异常.我发现这个错误是由 任何扩展 class 引起的。如果 ExampleQuest 不会扩展 Quest,则一切正常。我的 Quest class 没有任何错误,因为如果我用其他东西扩展 ExampleQuest,我也会得到一个空指针异常。

---> 所以我的解释是 Playstate.addEntityListener(this) 中的 this 指的是扩展的 class 在这种情况下是 Quest 而不是 EntityListener。我该如何解决我的问题?

public class ExampleQuest extends Quest implements EntityListener {

    public ExampleQuest() {
        super();
        Playstate.addEntityListener(this); //gives me nullointer exception 
    }

    //implemented method
    public void entityDeathEvent(EntityEvent e) {

    }
}

这是我的 Playstate 的一部分 class:

public class Playstate {

    public static Set<EntityListener> entityListener;

    public Playstate() {
        entityListener = new HashSet<EntityListener>();
    }

    public static void addEntityListener(EntityListener listener) {
        entityListener.add(listener);
    }
}

编辑:这正常工作:

public class EventHandler implements EntityListener {

    public EventHandler() {
        Playstate.addEntityListener(this);
    }
}

之所以有效,是因为 EventHandler 实现了 class

你的字段entityListener是空的,因为它是静态的,你只在创建Playstate的对象时初始化字段。

可能 entityListeneraddEntityListener 都不应该是静态的。让他们成为实例成员。

public class Playstate {

    public Set<EntityListener> entityListener;

    public Playstate() {
        entityListener = new HashSet<EntityListener>();
    }

    public void addEntityListener(EntityListener listener) {
        entityListener.add(listener);
    }
}

关于您的编辑: 我们只能假设当您的 EventHandler 代码运行时,它会工作,因为您已经在其他地方创建了一个 Playstate 对象在你的代码中。

Playstate 使用静态事件侦听器意味着所有此类对象将共享事件侦听器,这是一个 >糟糕的< 想法。真的,让他们成为实例成员,你会过得更好。

public Playstate() {
    entityListener = new HashSet<EntityListener>();
}

public static void addEntityListener(EntityListener listener) {
    entityListener.add(listener);
}

entityListener static 变量在构造 PlayState 构造函数时被赋值。这是一个严重的设计问题:要么监听器是静态的,因此不关联到 PlayState 的任何实例,因此不应在每次创建实例时分配,要么它关联到给定实例,并且不应该静态。

侦听器和 addEntityListener() 方法不应是静态的。相反,任务应该引用 PlayState class.

的实例

此外,由于它是侦听器的集合,因此变量应命名为 entityListeners,而不是 entityListener

您获得 NPE 的原因是 entityListener 尚未初始化。 entityListener 尚未初始化的原因是您的代码需要先创建 Playstate 的实例,然后才能开始使用 addEntityListener 方法,但您调用 addEntityListener before 创建 Playstate.

的实例

这是错误的:static 变量不应在 instance 构造函数中初始化。你需要在声明中这样做,就像这样

public static Set<EntityListener> entityListener = new HashSet<EntityListener>();

或者在 static 初始化块中,像这样:

public static Set<EntityListener> entityListener;

static {
    entityListener = new HashSet<EntityListener>();
}

使 entityListener 成为一个实例变量也可以,但是您需要提供一种从 ExampleQuest 的构造函数的上下文中获取 Playstate 实例的方法。