1

だから私はあなたにコードの巨大なブロックを惜しまないで、追いかけます。2つのクラスがあります。1つは基本の「AbstractNode」クラスで、もう1つは「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を拡張しているので、このメソッドが有効なオーバーライドではない理由を誰かが説明できますか?

4

5 に答える 5

3

これは有効なオーバーライドではありませんが、ジェネリックが原因ではありません。

を持っている場合は、パラメータとして別のものを使用してそれAbstractNodeを呼び出すことができるはずであると期待するのは合理的です。ただし、でこのメソッドを定義することはありません。createEvent()AbstractNodeTokenRingNode

たとえば、今のところジェネリックを無視します。

AbstractNode n1 = new TokenRingNode();
AbstractNode n2 = new TokenRingNode();
n1.createEvent(n2); // this should work by the contract of AbstractNode, but you never define it
于 2012-04-13T08:20:02.457 に答える
2

AbstractNodeで、このための2つのジェネリックを定義してみることができます。

public abstract class AbstractNode <E extends NetworkEvent, A extends AbstractNode>
...
public abstract void createEvent(A destinationNode);

そしてそれを次のようにサブクラス化します

public class TokenRingNode extends AbstractNode<TokenRingEvent, TokenRingNode>
于 2012-04-13T08:49:34.287 に答える
1

問題は、スーパークラスコントラクトAbstractNode<E>がパラメーターとして受け入れることを約束していることですが、具体的には、そのクラスのみを期待しますTokenRingNode (したがって、受け入れることを約束したもののサブクラスです。したがって、サブクラスはスーパークラスよりも少ないクラスを受け入れます。契約の約束。

于 2012-04-13T08:20:52.173 に答える
1

イベントと宛先ノードは2つの異なるタイプを持つことができるため、AbstractNodeにもう1つのジェネリック型を追加する必要があります。

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 <EextendsNetworkEvent>をパラメーターとして受け入れるためです。ただし、TokenRingEventのみを受け入れるようにする必要があるため、型宣言を1レベル上にプッシュする必要があります。

于 2012-04-13T08:49:26.170 に答える
0

AbstractNode<TokenRingEvent>必ずしもそうではないため、TokenRingNodeオーバーライドすることはできません

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

public void createEvent(TokenRingNode destinationNode); 

ジェネリック/型消去とは関係ありません。署名が異なるだけです。AAbstractNode<TokenRingEvent> destinationNodeはaではありませんTokenRingMode(ただし、その逆です、はい)。

于 2012-04-13T08:53:25.850 に答える