是否可以在父类中声明的子类中实例化变量?有什么好处? 例如:
public class Animal{ Food foodType;}
public class Dog extends Animal{
public Dog(){
foodType=new Food();
}
}
答案 0 :(得分:1)
这样做有很多好处。实际上取决于你的设计。
我创造了一个例子,也许是我能做的更糟糕的例子,但我想它会让你澄清你的想法。我只是想跟着你的代码。
在此示例中,我们使用Strategy
设计模式和Inversion of Control
。您可以看到Animal对食物实施一无所知?考虑一下,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";
}
}
}
答案 1 :(得分:0)
优点:
例如 如果有DogFood类扩展Food,Dog可以实例化它(如果Dog知道DogFood)并且Animal不需要知道DogFood。
这简化了代码。
答案 2 :(得分:0)
由于food类型是Animal属性,并且对于特定子类始终相同,因此在Animal中将其设为final
,并通过Animal构造函数传递它。
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(子)都有一个foodType,而且不必填充父类的字段。责任是应该的。