2012-04-13 124 views
1

所以,我会为您提供巨大的代码块并切入正题。我有两个类:一个是基础“AbstractNode”类,另一个是“TokenRingNode”类。增加AbstractNode签名是这样的:关于继承的泛型混淆 - Java

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,所以有人可以告诉我为什么这个方法不是一个有效的覆盖?

回答

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> 
+0

这一行的东西这是我正在寻找的解决方案! – jcampos8782 2012-04-13 09:05:18

3

这不是一个有效的覆盖,但不是因为泛型。

如果您有AbstractNode,则可以合理地预计您应该能够以其他AbstractNode作为参数调用createEvent()。但是你从来没有在TokenRingNode上定义这个方法。

例如无视仿制药的时刻:

AbstractNode n1 = new TokenRingNode(); 
AbstractNode n2 = new TokenRingNode(); 
n1.createEvent(n2); // this should work by the contract of AbstractNode, but you never define it 
+0

这很有道理。 – jcampos8782 2012-04-13 08:49:37

+0

那么是提供第二个createEvent方法的唯一解决方案?例如:@Override第一个AND创建一个接受TokenRingNode的本质上调用第一个,但有一些强制转换?具体如下:public void createEvent(TokenRingNode destinationNode){ \t \t createEvent((AbstractNode )destinationNode); \t} – jcampos8782 2012-04-13 08:51:01

1

的问题是,超合同承诺,它接受AbstractNode<E>作为参数,但是,您希望TokenRingNode具体而言,这是唯一的那个(所以的子类的什么它承诺接受因此你的子类是接受比超合同承诺少类

+0

}对,我怎么能概括AbstractNode 来说一些沿着“某些类是AbstractNode 的子类” – jcampos8782 2012-04-13 08:45:52

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 <é延伸NetworkEvent>作为参数。但是你希望它只接受TokenRingEvent,这就是为什么你需要将类型声明提高一级。

0

AbstractNode<TokenRingEvent>不一定是TokenRingNode因此不能覆盖

public abstract void createEvent(AbstractNode<TokenRingEvent> destinationNode); 

public void createEvent(TokenRingNode destinationNode); 

这与泛型/类型擦除无关,签名是不同的。 A AbstractNode<TokenRingEvent> destinationNode不是TokenRingMode(但相反,是的)。