因此,我试图创建一个具有泛型函数的接口,该接口将被子类覆盖,但我找不到实现此目的的方法。
我认为一段代码会更加明确:
interface Agent<A extends Agent<A>> {
<W extends World> Iterable<Action<A,W>> percepts(W world);
<W extends World> void takeAction(Action<A,W> action, W world);
}
abstract class StrategistAgent<A extends StrategistAgent<A>> implements Agent<A> {
abstract public <W extends World> AgentStrategy<A,W> getStrategy();
abstract public <W extends World> void setStrategy(AgentStrategy<A,W> strategy);
@Override
<W extends World> Iterable<Action<A,W>> percepts(W world) {
return getStrategy().run(this, world);
}
}
interface AgentStrategy<A extends StrategistAgent<A>, W extends World> {
Iterable<Action<A,W>> run(A agent, W world);
void init(A agent, W world);
}
错误:AgentStrategy类型的方法run(A,World)不适用于自变量(StrategistAgent,W)
但我不能写:
StrategistAgent<A extends StrategistAgent<A>, W extends World>
编辑:好的,我遵循了马克·彼得斯的建议,并删除了setStrategy方法。应该现在工作。
最佳答案
没错,正如您现在可能已经发现的那样,问题是没有什么可以说是您的错误发生的地方,this
是A
的一个实例。这就是我说泛型确实不是用于这种自引用类型的时候得到的。
但是,您的设计中还存在其他问题。对于初学者,设置策略时接受的W
可能与调用W
时得到的percept
完全不同。
那么您的前进方向是什么?好吧,我再次认为这取决于您的粘合代码,即创建代理和策略并将它们组合在一起的东西。
由于该粘合代码很可能会确切地知道它要处理的是哪种类型的代理和策略,因此使setStrategy
抽象可能根本无法从中受益。一旦它不是抽象的,您就可以在每个子类中对其进行处理。
实际上,子类所需的全部是受保护的方法getStrategy
。而且,如果您要强制所有子类提供该功能,则也可以强制它们也返回A
:
abstract class StrategistAgent<A extends StrategistAgent<A>> implements Agent<A> {
protected abstract <W extends World> AgentStrategy<A,W> getStrategy();
protected abstract A getSelf();
@Override
public <W extends World> Iterable<Action<A,W>> percepts(W world) {
return this.<W>getStrategy().run(getSelf(), world);
}
}
因此,这是一种解决方案。不过,我将不得不再考虑一些更优雅的方法。
关于java - Java中具有泛型的策略模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8116173/