OO编程中的子类型和继承有什么区别?

Mic*_*gus 16 oop computer-science

我找不到主要的区别.当我们可以使用继承并且我们可以使用子类型时,我很困惑.我找到了一些定义,但不是很清楚.

面向对象编程中的子类型和继承有什么区别?

adi*_*ino 26

除了已经给出的答案之外,这里还有一篇我认为相关的文章的链接.摘录:

在面向对象的框架中,当在类的层次结构中组织抽象数据类型时,继承通常作为与子类型相关联的特征呈现.然而,这两者是正交的想法.

  • 子类型是指接口的兼容性.类型BA如果A也可以在类型的对象上调用可以在类型的对象上调用的每个函数的子类型B.
  • 继承是指实现的重用.如果某些函数是根据函数编写的,则类型B继承自另一种类型.ABA

但是,子类型和继承不需要齐头并进.考虑数据结构deque,一个双端队列.甲双端队列支持在两端的插入和删除,因此它具有四种功能insert-front,delete-front,insert-reardelete-rear.如果我们只使用insert-rear,delete-front我们得到一个正常的队列.在另一方面,如果我们只使用insert-frontdelete-front,我们得到了一个堆栈.换句话说,我们可以根据deques,数据类型StackQueue继承来实现队列和堆栈Deque.另一方面,既不是Stack也不Queue是亚型,Deque因为它们不支持所提供的所有功能Deque.事实上,在这种情况下,Deque是两者的亚型StackQueue!

我认为Java,C++,C#和他们的同类已经引起了混淆,正如已经指出的那样,它们将这两个想法合并到一个类层次结构中.但是,我认为上面给出的例子以一种与语言无关的方式对这些想法进行公正审判.我相信其他人可以举出更多例子.

  • 这是一个完美的摘录.谢谢分享帮助清除了我的疑虑. (3认同)

Oak*_*Oak 10

一位亲戚不幸去世了,离开了他的书店.

您现在可以阅读所有的书在那里,卖给他们,你可以看看他的账户,他的客户名单等,这是继承 -你所拥有的一切相关了.继承是代码重用的一种形式.

您也可以自己重新打开书店,承担所有亲戚的角色和责任,即使您添加了自己的一些更改 - 这是子类型 - 您现在是书店老板,就像您以前的亲戚一样.

子类型是OOP的一个关键组件 - 您有一种类型的对象,但它满足另一种类型的接口,因此可以在其他对象可以使用的任何地方使用.

在你在问题中列出的语言--C++,Java和C#中 - 两者(几乎)总是一起使用,因此从某些东西继承的唯一方法是对其进行子类型化,反之亦然.但其他语言并不一定融合这两个概念.


Man*_*rse 6

继承是获取超类型的属性(和/或功能).例如:

class Base {
    //interface with included definitions

}

class Derived inherits Base {
    //Add some additional functionality.
    //Reuse Base without having to explicitly forward
    //the functions in Base
}
Run Code Online (Sandbox Code Playgroud)

在这里,a Derived不能在Base预期的地方使用,但能够Base在添加行为或改变某些Base行为方面时与a类似地行动.通常,Base它将是一个小助手类,它为某些常用功能提供接口和实现.

子类型多态性是关于实现接口,因此能够在运行时替换该接口的不同实现:

class Interface {
    //some abstract interface, no definitions included
}

class Implementation implements Interface {
    //provide all the operations 
    //required by the interface
}
Run Code Online (Sandbox Code Playgroud)

这里,Implementation可以在任何Interface需要的地方使用,并且可以在运行时替换不同的实现.目的是允许使用的代码Interface更广泛地使用.

你的困惑是合理的.Java,C#和C++都将这两个想法混合成一个单独的层次结构.但是,这两个概念并不相同,并且确实存在将两者分开的语言.


fre*_*low 5

如果在C++中私下继承,则可以在不进行子类型的情况下获得继承.那是,给定:

class Derived : Base        // note the missing public before Base
Run Code Online (Sandbox Code Playgroud)

你不能写:

Base * p = new Derived();   // type error
Run Code Online (Sandbox Code Playgroud)

因为Derived不是子类型Base.您只是继承了实现,而不是类型.

  • 从技术上讲,你仍然可以使用私有继承进行子类型化,只是子类型是私有的... (3认同)