2017-08-17 6 views
2

私はそれ自身LifeformのサブクラスであるAnimalのサブクラスであるいくつかのクラスを持っています。これらのクラスはすべて、常にそれ自身のタイプのものである子供を持っているので、ジェネリックです。下記の簡体字コード:ほとんどの生命体が子供を識別するための方法は、生命体のクラスであっても、子供を持っていないことをジェネリックがJavaのジェネリックのタイプとして参照するジェネリックスを持つクラス

public abstract class Lifeform { 
    private <L extends Lifeform> L findChild(Class<L> lifeformType) { 
     /* Do some stuff with lifeformType to find child */ 
     ... 
     return child; 
    } 
} 

注:findChildが継承されたメソッドである

public class Animal<T extends Animal> extends Lifeform { 
    T child; 

    private void initiate() { 
     setChild(Animal.class); 
    } 

    public void setChild(Class<T> animalType) { 
     T foundChild = findChild(animalType); 
     foundChild.setParent(this); 
     this.child = foundChild; 
    } 
} 

Animal.initiate()でsetChild(Animal.class)を呼び出そうとすると、コンパイルエラーが発生します。

非互換タイプ:のjava.lang.Class <動物は>のjava.lang.Class < Tに変換することができない>

Tは、動物を拡張し、なぜ私はAnimal.classを使用することができませんここのパラメータ?私はそのような一般的なからクラスを取得することはできません実現、および一般的な解決策はただクラスを追加することがわかっしかし

当初、私は、引数なしでsetChildを作成し、

findChild(T.class) 

を実行しようとしましたどのように私が今持っているもので終わったかというパラメータとして。

public class Bat extends Animal<Bat> { 
    private void fly() { 
     setChild(Bat.class); 
     child.fly(); 
    } 
} 

は、残念ながら、私は実際にはサブタイプなし動物のインスタンスを必要とするいくつかのケースがあるので、私はできるようにしたい、私はサブクラスでsetChildを使用しようと

私は何の問題を持っていません型をAnimalでsetChildに設定します。

おそらく、私はおそらく、Animalのための余分なサブクラスを作成し、その代わりにsetChildメソッドを含む抽象クラスAnimalAbstractを持つことができると思います。しかし、これは、どのように使用されているかに応じて、Animalからメソッドを分離する必要があることを意味します。

これを行う別の方法はありますか?

+0

ない方法あなたの 'Lifeform'インターフェースはどうですか? –

+0

@AdamArold抽象クラスです。私は単純化した形で上に追加しました。 – EJS

答えて

1

は、この問題に対処するための一つの方法は、子供のクラスへの参照を保持することであると私には思える:

public class Animal<T extends Animal> extends Lifeform { 
    protected final Class<T> childClass; 
    T child; 

    public Animal(Class<T> childClass) { 
     this.childClass = childClass; 
    } 

    protected void initiate() { 
     setChild(childClass); 
    } 

    public void setChild(Class<T> animalType) { 
     T foundChild = findChild(animalType); 
     foundChild.setParent(this); 
     this.child = foundChild; 
    } 
} 

バットクラスは、その後になる:

public class Bat extends Animal<Bat> { 
    public Bat() { 
     super(Bat.class); 
    } 

    private void fly() { 
     setChild(Bat.class); // or initiate(); 
     child.fly(); 
    } 
} 
関連する問題