在子类中实例化变量

时间:2016-10-23 21:51:03

标签: java instantiation

是否可以在父类中声明的子类中实例化变量?有什么好处? 例如:

public class Animal{ Food foodType;}
public class Dog extends Animal{ 
   public Dog(){
       foodType=new Food();
   }
}

3 个答案:

答案 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,而且不必填充父类的字段。责任是应该的。