多态性与继承
2022-09-02 03:28:54
假设我有两个类:动物和狗。狗是动物的一个子类。我执行以下代码:
Animal a = new Dog();
现在,我可以通过 a 变量调用 Dog 类的方法。
但我的问题是:如果我可以通过Dog对象(继承)调用Animal的所有方法,那么我为什么要使用多态性原理呢?我只能声明:
Dog d = new Dog();
有了这个声明,可以使用动物的所有方法和狗的方法。那么为什么要使用多态性呢?非常感谢您的回答。
假设我有两个类:动物和狗。狗是动物的一个子类。我执行以下代码:
Animal a = new Dog();
现在,我可以通过 a 变量调用 Dog 类的方法。
但我的问题是:如果我可以通过Dog对象(继承)调用Animal的所有方法,那么我为什么要使用多态性原理呢?我只能声明:
Dog d = new Dog();
有了这个声明,可以使用动物的所有方法和狗的方法。那么为什么要使用多态性呢?非常感谢您的回答。
在Java中,多态性和继承性的概念是“焊接在一起”的;一般来说,它不必是这样的:
有些语言的继承与多态性分离:
virtual)回到Java,使用多态性的原因是将代码与其反方实现的细节分离:例如,如果您可以编写适用于各种动物的方法,那么当您添加更多子类或实现时,该方法将仍然适用。这与一种与狗紧密耦合的方法形成鲜明对比。Feed(Animal animal)AnimalFeed(Dog dog)
至于
Dog d = new Dog();
声明去,没有一般的理由来避免这一点,如果你知道你的方法的其余部分专门处理狗。但是,在许多情况下,后者并非如此:例如,您的类或方法通常对确切的实现不敏感,例如
List<Integer> numbers = new ArrayList<Integer>();
在这种情况下,您可以替换为 ,并且知道您的代码将要编译。相反,如果您的列表被声明为 ,则这种切换可能不是确定的。new ArrayList<Integer>()new LinkedList<Integer>()numbersArrayList<Integer> numbers
这称为“编程到接口”。Stack Overflow上有一个很好的答案来解释它。
您可以拥有该类的其他实现,例如 .然后你可以说AnimalCat
Animal a = new Dog();
Animal b = new Cat();
您可以调用类的方法,而不关心它到底是哪个实现,多态性将调用正确的方法。例如:Animal
a.speak(); // "Woof"
b.speak(); // "Meow"
真的,这不是“多态性与继承”,而是“使用继承的多态性”。