继承和多态之间的主要区别是什么?

时间:2011-06-10 15:00:18

标签: java oop inheritance polymorphism

我今天在模块开卷考试结束时遇到了这个问题,发现自己迷路了。我正在阅读Head first Java,两个定义似乎完全相同。我只是想知道主要区别在于我自己的想法。我知道有很多类似的问题但是,我没有看到哪些问题提供了明确的答案。

17 个答案:

答案 0 :(得分:259)

继承是指'class'派生自现有的'class'。因此,如果您有一个Person课程,那么您的Student课程会延伸PersonStudent 继承所有{{1} }} 具有。您在Person中的字段/方法上放置的访问修饰符有一些细节,但这是基本的想法。例如,如果Person上有私有字段,则Person将无法看到它,因为其私有字段和私有字段对子类不可见。

多态性处理程序如何决定应该使用哪种方法,具体取决于它具有什么类型的东西。如果您有一个Student,其Person方法,并且您的read扩展了Student,其Person具有自己的实现,调用方法是由运行时为您确定的,具体取决于您是read还是Person。这有点棘手,但是如果你做了像

这样的事情
Student

学生上的读取方法被调用。这就是多态性的作用。您可以执行该分配,因为Person p = new Student(); p.read(); Student,但运行时足够聪明,知道Person的实际类型是学生

请注意,不同语言的细节不同。例如,您可以在javascript中继承,但它与Java中的工作方式完全不同。

答案 1 :(得分:183)

继承是指使用子类中超类的结构和行为

多态性是指更改子类中超类的行为

答案 2 :(得分:58)

多态性:以类似方式处理不同类型对象的能力。例如:长颈鹿和鳄鱼都是动物,动物可以Move。如果你有一个Animal的实例,那么你可以在不知道或关心它是什么类型的动物的情况下致电Move

继承:这是同时实现多态性和代码重用的一种方法。

其他形式的多态: 还有其他实现多态的方法,比如接口,它只提供多态性但没有代码重用(有时代码完全不同,例如Snile的MoveMove的完全不同狗,在这种情况下,接口将是更好的多态选择。

在其他动态语言中,可以使用Duck Typing实现多态,即类甚至不需要共享相同的基类或接口,它们只需要一个具有相同名称的方法。或者像Javascript一样更加动态,你甚至根本不需要类,只需一个具有相同方法名称的对象就可以多态使用。

答案 3 :(得分:17)

主要区别在于多态性是继承的具体结果。多态性是在运行时根据对象的类型确定要调用的方法的位置。当您有一个类继承另一个类并覆盖特定方法时,会出现这种情况。但是,在普通继承树中,您不必重写任何方法,因此并非所有方法调用都必须是多态的。那有意义吗?所有福特汽车都是汽车类似的问题,但并非所有的汽车都是福特(尽管不是......)。

此外,多态性处理方法调用,而继承也描述数据成员等。

答案 4 :(得分:12)

在Java中,两者密切相关。这是因为Java使用一种称为“动态调度”的方法调用技术。如果我有

public class A {
  public void draw() { ... }
  public void spin() { ... }
}

public class B extends A {
  public void draw() { ... }
  public void bad() { ... }
}

...

A testObject = new B();

testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A

然后我们看到B从A继承spin。然而,当我们尝试操纵对象就好像它是A类时,我们仍然得到了draw的B行为。 draw行为是多态的。

在某些语言中,多态性和继承并不是非常密切相关。例如,在C ++中,未声明为虚拟的函数是继承的,但不会动态调度,因此即使使用继承,也不会获得该多态行为。

在javascript中,每个函数调用都是动态调度的,并且您的输入类型较弱。这意味着你可以拥有一堆不相关的对象,每个对象都有自己的draw,有一个函数迭代它们并调用函数,每个都表现得很好。你有自己的多态绘制而不需要继承。

答案 5 :(得分:12)

多态性: 假设您为一家销售钢笔的公司工作。所以你创建了一个非常好的类“Pen”来处理你需要了解的关于笔的所有内容。您可以使用Pen类编写各种类别来计费,发货,创建发票。一天的老板来了,说:“好消息!公司正在发展,我们现在正在销售Books& CD!”这不是一个好消息,因为现在你必须改变每个使用Pen的课程来使用Book&光盘。但是,如果您最初创建了一个名为“SellableProduct”的接口,并且Pen实现了此接口,那该怎么办呢?然后你可以编写所有的发货,发票等类来使用该接口而不是Pen。现在你所要做的就是创建一个名为Book&的新类。 CompactDisc实现了SellableProduct接口。由于多态性,所有其他类可以继续工作而不会发生变化!有意义吗?

因此,它意味着使用继承,这是实现多态的方法之一。

在类/接口中可以实现多态,但继承始终在2个或更多类/接口之间。继承总是符合“is-a”关系,而它并不总是与多态(它可以符合“is-a”/“has-a”关系。

答案 6 :(得分:6)

继承更像是一个静态的东西(一个类扩展另一个),而多态是一个动态/运行时的东西(一个对象的行为根据它的动态/运行时类型而不是它的静态/声明类型)。

E.g。

// This assignment is possible because B extends A
A a = new B();
// polymorphic call/ access
a.foo();

- >虽然a的静态/声明类型是A,但实际的动态/运行时类型是B,因此a.foo()将执行B中定义的foo而不是A中的。

答案 7 :(得分:3)

多态性是一种表达具有相似特征的对象类型之间的共同行为的方法。它还允许通过覆盖创建这些特征的变体。继承是通过对象层次结构实现多态性的一种方式,其中对象表达关系和抽象行为。但它并不是实现多态的唯一方法。原型是表达与继承不同的多态的另一种方式。 JavaScript是使用原型的语言的示例。我想也有其他方法。

答案 8 :(得分:3)

Oracle文档准确地引用了这种差异。

inheritance: 一个类从其所有超类继承 字段和方法 ,无论是直接还是间接。 子类可以覆盖它继承的方法,也可以隐藏它继承的字段或方法。 (请注意,隐藏字段通常是糟糕的编程习惯。)

polymorphism: 多态性是指生物学中的一个原则,其中有机体或物种可以有许多不同的形式或阶段。这个原则也可以应用于面向对象的编程和Java语言之类的语言。 类的子类可以定义自己的独特行为,但可以共享父类的一些相同功能。

多态不适用于字段。

相关文章:

Polymorphism vs Overriding vs Overloading

答案 9 :(得分:3)

继承是与代码重用相关的概念。例如,如果我有一个父类说Animal并且它包含某些属性和方法(对于此示例说makeNoise()sleep()),我创建两个名为Dog的子类和Cat。由于狗和猫都以相同的方式进入睡眠状态(我认为),因此无需在sleep()Dog子类中为Cat方法添加更多功能。父类Animal。然而,Dog吠叫和Cat喵喵叫,所以虽然Animal类可能有制作噪音的方法,但是狗和猫相对于彼此和其他动物产生不同的噪音。因此,需要针对其特定类型重新定义该行为。从而定义了多态性。希望这会有所帮助。

答案 10 :(得分:1)

多态继承力的一种作用。它只能在相互扩展的类中发生。它允许您在不知道类的确切类型的情况下调用类的方法。此外,多态性确实会在运行时发生。

例如,Java多态性示例:

enter image description here

继承使派生类共享其基类的接口和代码。它发生在编译时

例如,Java平台中的所有类都是对象的后代(图片由Oracle提供):

enter image description here

要详细了解Java inheritanceJava polymorphism

答案 11 :(得分:0)

通过 Inheritance (继承)实现在超类中定义-因此,行为将被继承。

class Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}

class Dog extends Animal;

具有多态性的实现是在子类中定义的-因此仅继承 interface

interface Animal
{
  void move(double newLocation);
}

class Dog implements Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}

答案 12 :(得分:0)

多态是通过Java中的继承实现的。

public class Animal {}
public interface Herbivore {}
public interface Carnivore {}
public interface Pet {}

public class Hamster extends Animal implements Herbivore implements Pet () {}
public class Cat extends Animal implements Carnivore implements Pet () {}

Hamster类从AnimalHerbivorePet继承 结构 以展示 家养宠物的多态行为主义

Cat类继承了来自AnimalCarnivorePet 结构 ,以展示 < em>家养宠物的多态行为主义

答案 13 :(得分:0)

继承是一种多态,实际上继承是动态多态。因此,当您删除继承时,您不能再覆盖。

答案 14 :(得分:0)

如果您使用JAVA,它就像这样简单:

多态性使用的是继承的方法,但是&#34;覆盖&#34;他们做一些不同的事情(或者如果你称之为超级,那么就不会在技术上做多态)。

如果我错了,请纠正我。

答案 15 :(得分:0)

多态的主要目的:为超类创建引用变量并保持子类对象=&gt;对象可以执行多个行为

继承中,子类继承超类的属性。

答案 16 :(得分:0)

继承是指A类从其所有父项继承所有非静态受保护/公共方法/字段直到Object。