gpt4 book ai didi

java - 具有扩展枚举泛型的通用接口(interface)

转载 作者:行者123 更新时间:2023-12-02 12:56:46 24 4
gpt4 key购买 nike

我正在尝试编写一个通用的事件系统。为此,我想为 EventHandler 创建一个界面像这样*(这不起作用)*:

public interface GameEventHandler<I extends GameEvent<TYPE extends Enum<?>, ATT extends Enum<?>>> {
public void handleEvent(final GameEvent<TYPE, ATT>... e);
public void registerListener(final GameEventListener<I> listener,
final TYPE... type);
public void unregisterListener(final GameEventListener<I>... listener);
public void unregisterAllListener();
public void unregisterAllListener(final I... type);
public void processEvents();
public void processEvents(final int maxTimeInMS);
}

但这并不像我“认为”的那样有效。

事件本身是一个通用元素,非常简单:

public class GameEvent<T extends Enum<?>, S extends Enum<?>> {
private HashMap<S, String> values;
private T type;

public void init(T type) {
this.type = type;
}

public T getType() {
return this.type;
}

public void addMessage(S t, String value) {
this.values.put(t, value);
}

public void getMessage(S t) {
this.values.get(t);
}
}

如果我实现HandlerInterface我喜欢让它仍然通用,所以有类似 DefaultHandler<GameEvent<TypeEnum, AttributEnum>>() 的东西来初始化它。因此,您可以使用接口(interface)创建自己的处理程序或使用 DefaultHandler我提供但仍然可以使用您自己的 Enums .

目前我能够创建这样的界面:

public interface GameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends Enum<?>, ATT extends Enum<?>> 

但我没有得到 DefaultHandler 泛型的实现

public class DefaultGameEventHandler implements GameEventHandler<GameEvent<EventTypes, AttributeTypes>, EventTypes, AttributeTypes>  // not generic those are testing Enums

那我做错了什么?有可能像我想要的那样吗?

最佳答案

说实话,我不确定我是否完全理解您的要求。但如果您想让 DefaultGameEventHandler 尽可能通用,我建议采用以下方法:

不要让 GameEventHandler 接口(interface)接受 Enum 作为通用 EventType 和 AttributeType,而是让 GameEventHandler 接口(interface)接受 EventType 接口(interface)和 AttributeType 接口(interface):

public interface GameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends EventType, ATT extends  AttributeType> {

public void handleEvent(final GameEvent<TYPE, ATT>... e);
public void registerListener(final GameEventListener<I> listener, final TYPE... type);

public void unregisterListener(final GameEventListener<I>... listener);

public void unregisterAllListener();
public void unregisterAllListener(final I... type);

public void processEvents();
public void processEvents(final int maxTimeInMS);

}

下面是相应的接口(interface)和GameEvent类:

public interface EventType {
// common functionality of EventTypes, if any
}

public interface AttributeType {
// common functionality of AttributeTypes , if any
}

public class GameEvent<T extends EventType, S extends AttributeType> {
private HashMap<S, String> values;
private T type;

public void init(T type) {
this.type = type;
}

public T getType() {
return this.type;
}

public void addMessage(S t, String value) {
this.values.put(t, value);
}

public void getMessage(S t) {
this.values.get(t);
}
}

然后您可以创建任意数量的实现这些接口(interface)的枚举:

enum MyEventTypes implements EventType{TYPE_1,TYPE_2,TYPE_3}

enum MyAttributeTypes implements AttributeType{ATT_1,ATT_2,ATT_3}

如果您绝对需要接口(interface)来提供 Enum 类的功能,您仍然可以在接口(interface)中指定它,如下所示:

public interface EventType {
Enum<?> asEnum();
}

enum MyEventTypes implements EventType{
TYPE_1,TYPE_2,TYPE_3;
@Override
public Enum<?> asEnum() {return this;}
}

现在您可以创建一个实现 GameEventHandler 接口(interface)的通用 DefaultGameEventHandler 类:

public class DefaultGameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends EventType, ATT extends  AttributeType> implements GameEventHandler<I, TYPE, ATT>{ 

@Override
public void handleEvent(GameEvent<TYPE, ATT>... e) {
//...
}
@Override
public void registerListener(GameEventListener<I> listener, TYPE... type) {
//...
}
@Override
public void unregisterListener(GameEventListener<I>... listener) {
//...
}
@Override
public void unregisterAllListener() {
//...
}
@Override
public void unregisterAllListener(I... type) {
//...
}
@Override
public void processEvents() {
//...
}
@Override
public void processEvents(int maxTimeInMS) {
//...
}
}

您可以使用枚举实例化 DefaultGameEventHandler

//MyEventTypes and MyAttributeTypes are enums implementing EventType respectively AttributeType
DefaultGameEventHandler<GameEvent<MyEventTypes, MyAttributeTypes>, MyEventTypes, MyAttributeTypes> handler = new DefaultGameEventHandler<>();
GameEvent<MyEventTypes, MyAttributeTypes> event = new GameEvent<>();
event.addMessage(MyAttributeTypes.ATT_1, "some Message");
event.init(MyEventTypes.TYPE_1);
handler.handleEvent(event);
switch (event.getType()) {
case TYPE_1:
System.out.println("TYPE_1");
break;
case TYPE_2:
System.out.println("TYPE_2");
break;
case TYPE_3:
System.out.println("TYPE_3");
break;
default:
break;
}

或者也可以使用接口(interface)或实现接口(interface)的任何类:

DefaultGameEventHandler<GameEvent<EventType, AttributeType>, EventType, AttributeType> handler = new DefaultGameEventHandler<>();
GameEvent<EventType, AttributeType> event = new GameEvent<>();
event.addMessage(MyAttributeTypes.ATT_1, "some Message");
event.init(MyEventTypes.TYPE_1);
handler.handleEvent(event);
EventType type = event.getType();
// To switch on the type you could use the asEnum() method
// and cast the type to the corresponding enum if possible:
if (type.asEnum().getClass() == MyEventTypes.class) {
MyEventTypes t = (MyEventTypes)type.asEnum();
switch (t) {
case TYPE_1:
System.out.println("TYPE_1");
break;
case TYPE_2:
System.out.println("TYPE_2");
break;
case TYPE_3:
System.out.println("TYPE_3");
break;
default:
break;
}
}
// Or you could also directly switch on the name of the enum (not recommended!):
switch (type.asEnum().name()) {
case "TYPE_1":
System.out.println("TYPE_1");
break;
case "TYPE_2":
System.out.println("TYPE_2");
break;
case "TYPE_3":
System.out.println("TYPE_3");
break;
default:
break;
}

编辑 - 回复 BennX 的评论:

I think, that it would be rather good just to define the Eventhandlers and GameEvents with 2 Enums. But i think its not possible just with enums as you already marked.

实际上我不想表明,使用枚举是不可能的。如果您愿意,您可以将我的示例中的接口(interface)完全替换为枚举:

public class GameEvent<T extends Enum<?>, S extends Enum<?>>

public interface GameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends Enum<?>, ATT extends Enum<?>>

public class DefaultGameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends Enum<?>, ATT extends Enum<?>> implements GameEventHandler<I, TYPE, ATT>

但是为什么要对 GameEventHandler 的最终用户强制使用枚举呢?如果您的 EventType 和 AttributeType 中不需要任何通用功能,那么您甚至可以根本不使用任何枚举或接口(interface),并使 GameEventHandler 完全通用:

public interface GameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE, ATT>

public class GameEvent<T, S>

public class DefaultGameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE, ATT> implements GameEventHandler<I, TYPE, ATT>

我在上面发布的示例代码(其中使用枚举实例化 DefaultGameEventHandler)仍然可以使用这个通用 GameEventHandler。但除了枚举之外,用户还可以决定使用最终整数、最终字符串或任何其他对象来表示事件和属性类型。

关于java - 具有扩展枚举泛型的通用接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21908768/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com