breed
あなたが「私の子供を作る」という意味だと仮定すると、これを行うには多くの方法があります。
反射
まず、反射を使用します。クラスに引数なしのコンストラクターがある場合、これはClass.newInstanceを呼び出すのと同じくらい簡単です。
public Animal breed() {
try {
return (Animal) getClass().newInstance();
} catch (Exception ex) {
// TODO Log me
return null;
}
}
すべてのサブクラスに引数なしのコンストラクターがない場合は、すべてのサブクラスに統一されたコンストラクターが必要です。たとえば、とがある場合はCat(int, String)
、Dog(int, String)
を介してコンストラクタを取得し、それをClass.getConstructor
呼び出す必要がありますnewInstance
。
return (Animal) getClass().getConstructor(int.class, String.class).newInstance(0, "Unnamed");
int
String
たとえば、ここには年齢と名前があります。これは、リフレクションを使用してこれを行う方法です。
プロバイダー
別の方法は、この単純なインターフェースを使用することです。
public interface Provider<T> {
T create();
}
次に、抽象クラスにコンストラクターでこのインスタンスを取得させます。
public abstract class Animal {
private final Provider<Animal> animalProvider;
protected Animal( ... , Provider<Animal> animalProvider) {
// ...
this.animalProvider = animalProvider;
}
public Animal breed() {
return animalProvider.create();
}
}
次に、サブクラスはProvider<Animal>
、サブクラスの新しいインスタンスを作成するスーパークラスにを渡します。
public class Dog extends Animal {
public Dog( ... ) {
super( ... , new DogProvider());
// ...
}
private static class DogProvider implements Provider<Animal> {
public Animal create() {
return new Dog( ... );
}
}
}
他のサブクラスについても同じようにします。
注:breed
「私のタイプを取得する」という意味の場合は、質問を編集してそのようにする必要があります。これがあなたの意図したことである場合、これは実行可能な解決策です。
public abstract class Animal {
protected final Breed breed;
protected Animal( ... , Breed breed) {
// ...
this.breed = breed;
}
public Breed getBreed() {
return breed;
}
}
データコンテナメソッドのget
/規則に従うことをお勧めします。set
Javaには、これらの命名規則を処理するように設計されたBeanクラスがあり、多くのプラットフォームで多かれ少なかれ標準となっています。サブクラスの場合:
public class Dog extends Animal {
public Dog( ... ) {
super( ... , new Breed( ... ));
// ...
}
}