0

次のクラスのセットがあります。

public abstract class GSObject<T extends GSObject<T>> {
    public abstract boolean matches(String toMatch);
    //Other functions
    public static <T extends GSObject<T>> T findMatch(List<T> objects, String toMatch){
        //Code that iterates through the list, seeing if one matches;
    }
}

public abstract class Phrase extends GSObject<Phrase> {
    //More code
}
public class Request extends Phrase{
    @Override
    public boolean matches(String toMatch){
        //Implementation of matches()
    }
}

次のコマンドRequest.findMatch(allRequests,chat);を実行すると、次のエラーが発生します。 Bound mismatch: The generic method findMatch(List<T>, String) of type GSObject<T> is not applicable for the arguments (List<Request>, String). The inferred type Request is not a valid substitute for the bounded parameter <T extends GSObject<T>>

私がそうPhrase.findMatch(allPhrases, chat);しても、エラーはスローされません。つまり、これは二重継承に関係しています。GSObject を拡張するクラスを拡張するクラスで動作する別の静的関数を作成する必要がありますか?

GSObject をインターフェースにすることを検討しましたが、クラスで (抽象的ではなく) 定義したいクラスがいくつかあります。

(3 つのクラスのいずれかで) 不足しているものはありますか、または関数を定義するインターフェイスを作成する必要がありますかmatches()(回避しようとしていること)?

4

1 に答える 1

0

1 つのオプションは、次のようPhraseに同じ方法でジェネリックにすることGSObjectです。

public abstract class Phrase<T extends Phrase> extends GSObject<T> {

public class Request extends Phrase<Request> {

このように、Request拡張GSObject<Request>します(コードとは異なり、Requestextends GSObject<Phrase>)。

別のオプションは、ワイルドカードを使用して、これらの依存型の一部を分離することです。たとえば、次のいずれかです。

    public static <T extends GSObject<T>> T findMatch(List<? extends T> objects, String toMatch){

    public static <U extends GSObject<?>> U findMatch(List<U> objects, String toMatch){

ただし、これを正しく行うのは難しい場合があります。このアプローチでは、Requestは引き続き任意の を処理できることをアドバタイズするList<? extends Phrase>ため、静的型システムの利点の一部が失われることに注意してください。(言い換えれば、これらのバージョンは、実際に想定されているよりもクラスをより寛容にします。)

3 番目のオプションは、上記の両方を行うことです。結局のところ、Request.findMatchを取得するのは理にかなっていList<? extends Request>ます。

コードを詳しく見ないと、これらのどれが自分のケースに最も適しているかを判断するのは困難です。

于 2013-06-09T16:30:20.513 に答える