因此,我将为您节省大量代码并切入追逐。我有两个类:一个是基本的“AbstractNode”类,另一个是“TokenRingNode”类。 AbstractNode的签名是这样的:
public abstract class AbstractNode <E extends NetworkEvent>
然后是TokenRingNode的签名:
public class TokenRingNode extends AbstractNode<TokenRingEvent>
我在AbstractNode中有一个方法:
public abstract void createEvent(AbstractNode<E> destinationNode);
我也尝试过:
public abstract <N extends AbstractNode<E>> createEvent (N destinationNode)
然后在TokenRingNode中,我用:
覆盖这个抽象方法public void createEvent(TokenRingNode destinationNode) { ... }
问题是,编译器不相信这是一个有效的覆盖,我不确定为什么。 TokenRingNode扩展了Abstract,所以有人可以向我说明为什么这个方法不是有效的覆盖?
答案 0 :(得分:3)
这不是有效的覆盖,但不是因为泛型。
如果您有AbstractNode
,那么您可以使用其他createEvent()
作为参数调用AbstractNode
,这是合理的。但是你永远不会在TokenRingNode
上定义这个方法。
e.g。暂时忽略了泛型:
AbstractNode n1 = new TokenRingNode();
AbstractNode n2 = new TokenRingNode();
n1.createEvent(n2); // this should work by the contract of AbstractNode, but you never define it
答案 1 :(得分:2)
您可以尝试在AbstractNode中为此定义两个泛型:
public abstract class AbstractNode <E extends NetworkEvent, A extends AbstractNode>
...
public abstract void createEvent(A destinationNode);
然后将其子类化为
public class TokenRingNode extends AbstractNode<TokenRingEvent, TokenRingNode>
答案 2 :(得分:1)
问题是超类合同承诺它接受AbstractNode<E>
作为参数,但是,你特别期望TokenRingNode
,它只是那些类中的一个(所以它承诺的子类)接受。因此你的子类接受的课程少于超类合同的承诺。
答案 3 :(得分:1)
您需要向AbstractNode添加一个更通用的类型,因为事件和目标节点可以有两种不同的类型:
public abstract class AbstractNode <E extends NetworkEvent, N extends AbstractNode<E, N>>
{
public abstract void createEvent(N destinationNode);
}
然后这将编译:
public class TokenRingNode extends AbstractNode<TokenEvent, TokenRingNode>
{
public void createEvent(TokenRingNode destinationNode){
}
}
你不能只做
public abstract <N extends AbstractNode<E>> createEvent (N destinationNode)
因为那时你声明createEvent方法接受任何AbstractNode&lt; E extends NetworkEvent&gt;作为参数。但是你希望它只接受TokenRingEvent,这就是你需要将类型声明推高一级的原因。
答案 4 :(得分:0)
AbstractNode<TokenRingEvent>
不一定是TokenRingNode
,因此您无法覆盖
public abstract void createEvent(AbstractNode<TokenRingEvent> destinationNode);
带
public void createEvent(TokenRingNode destinationNode);
它与泛型/类型擦除无关,签名只是不同。 AbstractNode<TokenRingEvent> destinationNode
不是TokenRingMode
(但相反,是)。