inheritance和多态之间的区别

我正在研究多态性。 我无法确定Java中有关这两个function的类比。

让我们说Animal类是一个具体的超类, CatDog作为它的子类。 我知道这是inheritance的一个例子。 但是不是Cat and Dog类, Animal类的多态?

我很清楚Java中的接口。 我无法理解为什么使用接口而不是具体类来解释多态。 可能是创建接口的整个目的是创建多态,但我想知道为什么接口而不是具体的类?

遗产

 class Animal{ public void speak(){ System.out.println("Speaking something");} } class Person extends Animal{ @Override public void speak(){ System.out.println("Hello..");} } 

多态性

 Animal a = new Person(); a.speak();// Hello 

多态性的字典定义是指生物学中的原理,其中生物体或物种可以具有许多不同的forms或阶段。 这个原则也可以应用于面向对象的编程和Java语言之类的语言。 类的子类可以定义它们自己的唯一行为,但是它们共享父类的一些相同function[…]


为什么接口?

你知道需要做什么,但是你希望实施者决定如何去做,你会让实施者强有力地实现这些东西

  • 当最佳使用的-的接口,在Java的

接口使用一种类型的多态,即Method overriding。

接口通常用作常用方法的契约。

我不知道接口是解释多态的最佳方法。 多态性是遗传的产物。 这是从观察者的角度看待inheritance层次结构时发生的事情。 每只动物都可以发出声音,但是当观察者实际上观察到动物发出声音时,猫会发出喵喵叫声。 当小狗叫喊时小狗拉着嘴。 多态性是使这些属性基于它们在inheritance层次结构中的位置隐式展示自身的能力。

接口是实现组合的一种方式。 您可以向其他相关或不相关对象可能具有或不具有的对象添加属性。 狗是一个流氓。 虽然这只猫很划伤。 其他不一定是动物遗传层次结构的东西也可以具有这些流口水和/或刮擦属性。

inheritance在Java中implements ,分别使用extendsimplements关键字作为超类或接口的方法/字段的简单扩展。 无论哪种方式,您都可以在子类中访问超类的公共和受保护数据成员,并且当从外部对子类进行操作时,只有公共数据成员。

举个例子,您可以定义几个类:

 class Animal { private int location; public Animal() { location = 0; } public void move() { location += 10; } public int getLocation() { return location; } } class Dog extends Animal { @Override public void move() { setLocation(getLocation() + 5); } } /* * The @Override flag is optional, but I prefer to put it there * to ensure that I am actually overriding a method or implementing * a method from an interface. */ class Cat extends Animal { @Override public void move() { setLocation(getLocation() + 15); } } 

所以DogCat都扩展了Animal – 这是一种inheritance关系。

多态性是完全不同的。 根据维基百科:

工业中多态性的主要用法(面向对象编程理论)是属于不同类型的对象响应同名的方法,字段或属性调用的能力,每个调用根据适当的类型特定行为。

用简单的英语术语来说,这只是意味着采取相同的想法或行动,并根据具体的对象类型以不同的方式实施。 在代码中:

 public static void main(String[] args) { Animal animalArray = { new Animal(), new Cat(), new Dog() }; for (Animal a : animalArray) { a.move(); } System.out.println("Animal location: " + animalArray[0].getLocation()); System.out.println("Cat location: " + animalArray[1].getLocation()); System.out.println("Dog location: " + animalArray[2].getLocation)); } 

这会产生输出:

 Animal location: 10 Cat location: 15 Dog location: 5 

请注意,每个对象, AnimalCatDog都可以作为Animal访问。 这是可能的,因为每个类都是或扩展Animal ,因此每个类将始终具有public方法move() ,在某些情况下只需重新定义。

接口的工作理念相同; 如果类扩展了接口,则可以保证接口中定义的每个方法都有一些实现,因此可以根据接口实现的方法使用它。

假装您已被聘用来创建编程语言,这是其中一项要求:

 1 > 3 should call code from the integer comparison library. 1.0 > 3.0 should call code from the floating point comparison library. "McDonald" > "MacDonald" should call code from the locale-aware string comparison library. 

该要求是“多态”,其中相同的文本(>运算符)根据情况(在这种情况下,操作数的类型)执行不同的操作。

您可以通过将整数,浮点数和字符串全部派生自同一基类,并将基类定义为具有虚拟比较运算符来满足这些要求。 这可能会变得混乱。 如果以后,语言用户想…

 blue > yellow 

…编译为执行颜色操作的代码,基类方法意味着颜色,字符串,浮点数和整数都是更一般基础的特殊情况。 我认为那会很奇怪。

另一种方法是为应用程序开发人员提供一种语言方式,以创建任意类型并说出它们支持的操作,并为库开发人员提供支持一组操作的任何类型的函数。 例如,您可以为支持比较和赋值运算符的任何类型编写排序例程。

这种方法称为接口,它的优点是它可以很好地处理真正非常不同的类型。