0

これは私のコードです:

public interface InterfaceA<J>{  
    // …
} 

public interface InterfaceB extends InterfaceA<String> {
    // …
} 

public interface InterfaceC extends InterfaceA<Long>{  
    // …
}

public class Creator<J, I extends InterfaceA<J>> {}

public abstract class Base<J, J1> implements InterfaceA<J> {    
    protected Creator<J, J1> creator;    

    protected Base() {
        creator=ObjectCreator.createCreator();
    }   
}

public class Extension1 extends Base<Integer> implements InterfaceB {
    // …
}

public class Extension2 extends Base<Double> implements InterfaceC {
    // …
}

持っていたいExtension1、持ってCreator<Integer, InterfaceB>Extension2たいCreator<Double, interfaceC>。パターンを見ますか?Creator<T1, T2>ここT1で、は直接の親のタイプであり、T2は上記のクラスによって実装されるインターフェースです。これを行う方法はありますか?誰でもコードを教えてもらえますObjectCreator.createCreator()か?

現在、私のコードは次のようになっています。

public class ObjectCreator {
    public static <J, I extends InterfaceA<J>> Creator<J, I> createCreator() {
        return new Creator();
    }
}

コード全体でエラーが発生しました。私は本当に混乱しています。ここで何が欠けていますか?

4

1 に答える 1

0

見逃したものがたくさんあります。コンパイル バージョンは次のようになります。

package scratch;

interface InterfaceA<J> {
    // …
}

interface InterfaceB extends InterfaceA<String> {
    // …
}

interface InterfaceC extends InterfaceA<Long> {
    // …
}

class Creator<J, I extends InterfaceA<J>> {
}

abstract class Base<J, I extends InterfaceA<J>> {
    protected Creator<J, I> creator;

    protected Base(Class<J> jClass, Class<I> iClass) {
        creator = ObjectCreator.createCreator(jClass, iClass);
    }
}

class Extension1 extends Base<String, InterfaceB> implements InterfaceB {
    protected Extension1() {
        super(String.class, InterfaceB.class);
    }
}

class Extension2 extends Base<Long, InterfaceC> implements InterfaceC {
    protected Extension2() {
        super(Long.class, InterfaceC.class);
    }
}

class ObjectCreator {
    public static <J, I extends InterfaceA<J>> Creator<J, I>
    createCreator(Class<J> jClass, Class<I> iClass) {
        return new Creator();
    }
}

重要な順不同:

  • hasのような署名を持つクラスがある場合、オブジェクトを型トークンとしてcreateCreator()渡す必要があります。ClassJava コンパイラは、戻り値を割り当てる変数の型に基づいて型を推測できません。Creatorその上、型の消去のためにとにかくそれらが必要です。そうしないと、指定された型に基づいて を 特殊化できませんでした。
    • 2 つの型パラメーターを使用している場合Base<J, I>、クラスを拡張すると、これらの型パラメーターの両方を使用する必要があります。
    • あなたの拡張クラスの署名は奇妙でした。を持つことができないclass Extension1 extends Base<Integer, InterfaceA<String>>ため、 を持つことはできませんCreator<Integer, InterfaceA<String>>。明示的な型トークンを使用するcreateCreator()と、この制約を必要なすべての場所に伝播することを余儀なくされ、エラーの謎が少なくなります。と型パラメータBaseの間の制約から独立させることはできません。JI
于 2012-06-24T11:34:15.053 に答える