我对类似的泛型yesterday有疑问,作为解决方案,我在某些类中实现了一种自引用,如下所示:
public interface Action { }
public interface Result { }
public interface Player<A extends Action, R extends Result, P extends Player<A, R, P>> {
default public void onPostAction(final P target, final A action, final R result) { }
}
abstract public class GesturePlayer<A extends Action, R extends Result, P extends GesturePlayer<A, R, P>> implements Player<A, R, P> { }
abstract public class RPSPlayer extends GesturePlayer<RPSGesture, RPSResult, RPSPlayer> { }
public class RPSHumanPlayer extends RPSPlayer {
@Override
public void onPostAction(final RPSHumanPlayer target, final RPSGesture gesture, final RPSResult result) { }
}
此代码无法编译,我无法弄清楚原因
如果在@Override
我使用RPSPlayer
,它确实有效,但RPSHumanPlayer
只是它的一个子类,如果它不能与以下相同吗?
List<T> list = new ArrayList<>();
其中类型也定义为超类(List
resp RPSPlayer
),引用对象的类型作为子类(ArrayLast
resp RPSHumanPlayer
)。
我对这个问题的目的是收集有关泛型如何正常工作的见解,并且我希望保留RPSHumanPlayer
中定义的方法签名。
我认为我对泛型的理解:
T
是一个类型化参数,如List<String>
等。也可以将它用于自己的类和方法。这也捕获了T
。?
捕获所有可能的Object
个。用于确保某些东西是通用的而不是原始的。? extends T
捕获T
。此代码是用Java 8编写的。
答案 0 :(得分:2)
为了在RPSHumanPlayer
中实现所需的方法签名,您需要像这样生成RPSPlayer
:
abstract public class RPSPlayer<P extends RPSPlayer<P>> extends GesturePlayer<RPSGesture, RPSResult, P> { }
然后你可以定义:
public class RPSHumanPlayer extends RPSPlayer<RPSHumanPlayer>
在Java中,参数类型是方法签名的一部分,因此它们不能被更改(甚至不是子类)。从Java 5开始,你可以使用协变返回类型,但就这一点而言。
答案 1 :(得分:1)
你的问题归结为:
public interface Player {
default public void onPostAction(Player target) {}
}
public abstract class HumanPlayer implements Player {
@Override
public void onPostAction(HumanPlayer target) {}
}
这不起作用,因为onPostAction(HumanPlayer)
无法覆盖onPostAction(Player)
,因为如果使用不是Player
的{{1}}调用会发生什么?