親クラスで宣言された子クラスの変数をインスタンス化することは可能ですか?利点は何でしょうか? 例:子クラスの変数をインスタンス化
public class Animal{ Food foodType;}
public class Dog extends Animal{
public Dog(){
foodType=new Food();
}
}
親クラスで宣言された子クラスの変数をインスタンス化することは可能ですか?利点は何でしょうか? 例:子クラスの変数をインスタンス化
public class Animal{ Food foodType;}
public class Dog extends Animal{
public Dog(){
foodType=new Food();
}
}
利点:元については
。
DogFoodクラスがFoodを継承している場合、Dogはそれをインスタンス化できます(DogはDogFoodについて知っていて、AnimalはDogFoodについて知る必要はありません)。
これはコードを簡略化します。
これを行う利点はたくさんあります。実際にあなたのデザインに依存します。
例を作成しましたが、もっと悪い例がありましたが、あなたの心を明確にすると思います。私はちょうどあなたのコードに従おうとしました。
この例では、Strategy
デザインパターンとInversion of Control
を使用します。あなたは、動物が食品の実装について何も知らないことがわかりますか?それについて考えると、Animal.eat()
はeat()
メソッドを変更せずに複数の実装を実行できます。 OOPができることは少しです。
public class Main {
public static void main(String ... args){
Animal paul = new Dog("Paul");
Animal elsa = new Cat("Elsa");
paul.eat();
elsa.eat();
}
public static abstract class Animal {
private String name;
protected Food foodType;
public Animal(String name){
this.name = name;
}
public void eat() {
System.out.println("The " + name + " has eaten " + foodType.getAmount() + " " + foodType.foodName());
}
}
public static class Dog extends Animal {
public Dog(String name) {
super(name);
foodType = new DogFood();
}
}
public static class Cat extends Animal {
public Cat(String name) {
super(name);
foodType = new CatFood();
}
}
public interface Food {
int getAmount();
String foodName();
}
public static class DogFood implements Food{
@Override
public int getAmount() {
return 2;
}
@Override
public String foodName() {
return "beef";
}
}
public static class CatFood implements Food{
@Override
public int getAmount() {
return 5;
}
@Override
public String foodName() {
return "fish";
}
}
}
この例をありがとう。 Inversion of Controlは私のための火星の表現です。 – Alexis
'Inversion of Control'は理解しやすいです。ルールとして、オブジェクトがクラスを変更せずに異なる実装を実行できる場合、このクラスは 'IoC'を実装しています。例は 'Thread.class'であり、' IoC'を使ってこの実装について何も知らずに 'Runnable'実装の実行を処理します。 – Paulo
ありがとう、かなりシンプルな、ハァッ...もっと個人的な質問:デザインパターンを理解し、正しく使用するにはどのくらいの時間がかかりますか?ちょっと手掛かり... – Alexis
食品の種類は、常に特定の子クラスに同じ動物の特性であり、そして同様に、動物でfinal
行い、動物のコンストラクタを介して、それを渡します。
public class Animal {
public final Food foodType;
public Animal(Food foodType) {
this.foodType = foodType;
}
}
public class Dog extends Animal{
public Dog() {
super(new DogFood());
}
}
すべてのAnimal(child)にはfoodTypeがあり、1つは親クラスのフィールドを満たす必要はありません。責任はどこにあるべきかです。
変数が子に表示されている可能性があります。 – nickb
@nickbまだインスタンス化されていません。 – Toris
プロパティの修飾子が保護されている場合は、それを行うことができます。それがデフォルトの場合、あなたの子供が同じ親のパッケージに入っている場合にそれを行うことができます。もちろん公開されていれば、どこでもそれを行うことができます。 – Paulo