多态性与遗传

Ass*_*saf 18 java polymorphism

假设我有两个类:Animal和Dog.狗是动物的一个子类.我执行以下代码:

Animal a = new Dog();
Run Code Online (Sandbox Code Playgroud)

现在我可以通过一个变量调用Dog类的方法.

但我的问题是:如果我可以通过Dog对象(继承)调用所有Animal的方法而不是为什么我应该使用多态原理?我可以宣布:

Dog d = new Dog();
Run Code Online (Sandbox Code Playgroud)

有了这个声明,可以使用Animal的所有方法和Dog方法.那么为什么要使用多态?非常感谢您的回答.

das*_*ght 23

在Java中,多态性和继承的概念是"焊接在一起"; 一般来说,它不一定是这样的:

  • 多态性允许您在不知道类的确切类型的情况下调用类的方法
  • 继承允许派生类共享其基类的接口和代码

有些语言的继承与多态性分离:

  • 在C++中,您可以继承一个类而不会产生多态行为(即不要在基类中标记函数virtual)
  • 在Objective C中,您可以在不相关的类上实现一个方法,并从只知道方法签名的地方调用它.

回到Java,使用多态的原因是将代码与其对方的实现细节分离:例如,如果您可以编写Feed(Animal animal)适用于各种动物的方法,那么该方法将适用于您添加更多的子类或实现Animal.这与Feed(Dog dog)将与狗紧密耦合的方法形成对比.

至于

Dog d = new Dog();
Run Code Online (Sandbox Code Playgroud)

声明说,如果你知道你的方法的其余部分特别针对狗,那么没有一般理由可以避免这种情况.但是,在许多情况下,后者不是这种情况:例如,您的类或您的方法通常对确切的实现不敏感,例如

List<Integer> numbers = new ArrayList<Integer>();
Run Code Online (Sandbox Code Playgroud)

在这样的情况下,可以替换new ArrayList<Integer>()使用new LinkedList<Integer>(),并知道你的代码将编译.相反,如果你的numbers名单被宣布为ArrayList<Integer> numbers,那么这种转换可能并不确定.

这称为"编程到接口".Stack Overflow上有一个非常好的答案来解释它.


rge*_*man 5

您可以拥有Animal该类的其他实现,例如Cat. 那你可以说

Animal a = new Dog();
Animal b = new Cat();
Run Code Online (Sandbox Code Playgroud)

你可以调用Animal类的方法而不用关心它到底是哪个实现,多态会调用正确的方法。例如

a.speak();  // "Woof"

b.speak();  // "Meow"
Run Code Online (Sandbox Code Playgroud)

真的,这不是“多态与继承”,而是“使用继承的多态”。