适当的继承是什么意思?
答案 0 :(得分:4)
This thread给出了一个很好的总结:
当派生类“IS A”基类的专用类型时,会发生正确的继承。示例Cat是动物。
当一个类仅仅为了代码重用而继承而没有任何其他关系时,会发生不正确的继承。示例Cat从引擎继承。 Cat不是发动机,而是发动机和猫咕噜声。
答案 1 :(得分:3)
我想补充Justin和Baxter说的话。
正确继承这个术语并没有真正明确定义。正确使用继承是一个非常主观的问题......
考虑以下示例:
Bird
Ostrich
Ostrich
是否应继承Bird
?从动物学的角度来看,这是有道理的,但从计算机科学的角度来看......并非如此。如果Bird
有fly
方法,那么我应该如何处理Ostrich::fly
:x?
CS社区有一场战争。事实上,当从CS的角度来看,Circle
从Ellipse
继承而来时(或者反过来),你会经常看到这些书。
所以我自己的小定义:
考虑到接口为每个方法定义了精确的语义,如果每个方法的实现与指定的语义匹配,则具体类应该只从接口继承。
答案 2 :(得分:0)
当继承符合IS A关系时,而不是继承纯粹用于代码重用而没有超类对子进行逻辑包含。
答案 3 :(得分:0)
也许首先我们应该回想一下继承本身的价值。继承是代码重用和接口重用(多态)的机制。但是,通过使用组合和委托,您可以在不继承的情况下重用代码。在许多语言中,您可以拥有没有继承的多态性,但不是所有语言。在诸如C ++之类的强类型语言中,多态性本身是另一种重要的代码重用机制,只能使用继承来实现。实际上,C ++分别区分了接口和代码重用的公共和私有继承。稍后会详细介绍。
通常人们认为类的方法是与类的客户创建契约:它保证只要你调用满足某些前提条件的方法,该方法就会产生某些结果。 “正确”继承是这样的,即子类实例可以替换其父类而不违反父类的合同。也就是说,子类的方法都不应该覆盖其基类的方法,这些方法需要更严格的前置条件,也不能提供更多“更少”的结果。回到C ++,由于公共和私有继承之间存在明显的区别,前者是必需的,因此您可以将子类实例替换为基类实例,通常认为替换在语义上是正确的“正确”。否则为什么不使用私有继承?
Ostrich
是Bird
的有效子类吗?这取决于你对Bird
的抽象是什么?如果Bird
类有一个方法Bird::fly
可以做一些有形的事情,但是Ostrich::fly
会覆盖它以抛出一个异常并因此提供“少于”它的基类,我会说不。但是如果类Bird
没有fly
方法(还有另一个子类Flying_Bird
),那就没问题。
我的回答是,对于任何面向对象的语言而言,C ++的含义并不是一个糟糕的指导原则。在Python这样的语言中,多态性不需要继承层次结构,人们可能更倾向于仅使用继承来重用代码。如果这种重用被充分记录,则可能不是问题。但是当我看到一个类层次结构时,我的期望是子类可能会以多态方式使用。