【发布时间】:2021-04-07 12:21:13
【问题描述】:
我正在设置一个事件系统,我希望我的所有事件都扩展我创建的Event 类。但是,我还希望在任何时候都能够添加额外的 setCanceled 和 isCanceled 方法。
这是一个例子:
public class Event {}
public interface EventCancelable {
public default void setCanceled(boolean canceled) {...}
public default boolean isCanceled() {...}
}
public class PlayerEvent extends Event {
public Player player;
public PlayerEvent(Player player) {
this.player = player;
}
}
public class PlayerMovementEvent extends PlayerEvent implements EventCancelable {...}
如您所见,稍后我使用了一个接口来添加方法。 问题是如果事件被取消,我必须如何存储:
public interface EventCancelable {
Map<Object, Boolean> canceled = new HashMap<>();
public void setCanceled(boolean canceled) {
canceled.put(this, canceled);
}
public boolean isCanceled() {
return canceled.get(this);
}
}
注意,由于 Java 只允许静态字段,我必须创建一个映射来存储哪些事件被取消。这工作正常,但一段时间后,考虑到事件被非常频繁地调用,这将占用越来越多的内存。有没有办法在不使用界面的情况下添加可取消的功能,并且无需手动将代码放入我希望能够取消的每个事件中?我不能使用EventCancelable 类,从那时起PlayerMovementEvent 就不能同时扩展PlayerEvent 和EventCancelable,因为我不希望所有PlayerEvents 都可以取消.
或者,Java 是否足够聪明,可以清空不再使用的额外事件的映射,因为该映射仅在接口中使用,并添加了 this 作为参数?
【问题讨论】:
-
您不能在 Java 接口中声明非静态或非最终字段。
default方法也不能直接访问实例字段。所以答案是否定的。任何需要声明(实例)字段的功能都需要在类中实现。 -
@StephenC 是的,我得到了那部分,我在问是否有办法在不使用界面的情况下做到这一点。我认为这是一个不?
-
嗯,是的。使用类;例如将该功能放入您的
Event类中。 -
不,如果你的
Map还活着,那么它的所有内部条目也都是对Map的强烈引用。另一方面,WeakHashMap... -
所以创建一个扩展
PlayerEvent的CancellablePlayerEvent类。但无论哪种方式,实现实例字段和引用它的方法的唯一方法是将字段声明和相应的方法放入class。
标签: java class methods interface static