44

クラスEmailMonitor.javaによってサブクラス化された抽象クラスMonitor.javaがあります。

メソッド:

public abstract List<? extends MonitorAccount> performMonitor(List<? extends MonitorAccount> accounts)

Monitor.javaで定義されており、 EmailMonitor.javaでオーバーライドする必要があります。

現在、次のようにEmailMonitor.javaでオーバーライドされたメソッドがあります。

@Override
public List<EmailAccount> performMonitor(List<EmailAccount> emailAccounts) {
    //...unrelated logic
    return emailAccounts;
}

ただし、これによりコンパイル時エラーが発生します。

Name clash: The method performMonitor(List<EmailAccount>) of type EmailMonitor has the same erasure as performMonitor(Lis<? extends MonitorAccount> emailAccounts) of type Monitor but does not override it

EmailAccountは のサブクラスでMonitorAccountあるため、(少なくとも私の考えでは) このようにオーバーライドすることは完全に理にかなっています。ただし、コンパイラが私のロジックに満足していないのを見て、コンパイル時のチェックを維持しながら、すべての呼び出しが他のタイプのリストではなくEmailMonitor.performMonitor()のリストを受け取ることを確認しながら、これを正しく行うにはどうすればよいですか? EmailAccountMonitorAccount

4

2 に答える 2

36

いいえ、適切にオーバーライドしていません。オーバーライドとは、基本クラスへの有効な入力に対処できる必要があることを意味します。クライアントがこれを行った場合に何が起こるかを考えてみましょう:

Monitor x = new EmailMonitor();
List<NonEmailAccount> nonEmailAccounts = ...;
x.performMonitor(nonEmailAccounts);

あなたの説明を考えると、コンパイル時にエラーが発生するものは何もありませんが、明らかに間違っています。

Monitor監視できるアカウントの種類では一般的であるべきだと私には思われるので、EmailMonitor拡張する必要がありますMonitor<EmailAccount>。そう:

public abtract class Monitor<T extends MonitorAccount>
{
    ...
    public abstract List<? extends T> performMonitor(
        List<? extends T> accounts);
}

public class EmailMonitor extends Monitor<EmailAccount>
{
    @Override
    public abstract List<? extends EmailAccount> performMonitor(
        List<? extends EmailAccount> accounts)
    {
        // Code goes here
    }
}

ただし、呼び出しのジェネリックについては慎重に検討する必要があるかもしれませんperformMonitor。戻り値は何を意味するのでしょうか?

于 2008-10-27T11:56:23.500 に答える
10

ここに私自身の解決策があります。これは、Jon Skeet が取得しようとしていたものと同じだと思います...タイプミスなしで (彼の回答に対する私のコメントを参照してください)。

Monitor.javaクラス:

public abstract class Monitor <T extends MonitorAccount> {
  ...
  public abstract List<T> performMonitor(List<T> accounts);
  ..
}

EmailMonitor.java

public class EmailMonitor extends Monitor<EmailAccount> {
  ...
  public List<EmailAccount> performMonitor(List<EmailAccount> emailAccounts) {
    ..//logic...logic...logic
    return emailAccounts;
  }
  ...
}

この構成では、EmailMonitor.performMonitor()はコンパイル時に、他のタイプのFTPAccount、DBAccountなどではなく、 EmailAccountのリストを受け取ることを常にチェックします。生のリストを送信し、それを必要な型に強制しなければならないため、実行時の型キャスト例外が発生する可能性があります。

于 2008-10-27T14:59:27.577 に答える