Inheritance Is a Procedural Technique for Code Reuse

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

我们都知道继承是不好的,而组合优于继承是一个好主意,但我们真的明白为什么吗?在我找到的几乎所有关于这个主题的文章中,作者都说继承可能对你的代码有害,所以最好不要使用它。让我困惑的是这个”最好不要”部分;这是否意味着有时继承是有意义的?我几周前采访了David West(我最喜欢的关于面向对象编程的书《Object Thinking》的作者),他说继承在面向对象编程中根本不应该存在(完整视频)。也许韦斯博士是对的,我们应该完全忘记Java中的extends关键字,例如?

我认为我们应该这么做。而且我知道原因。

这不是因为我们引入了不必要的耦合,正如Allen Holub在他的为什么extends是邪恶的文章中所说的那样。他绝对是对的,但我相信这不是问题的根本原因。

作为一个英语动词,”inherit”有许多意思。我猜Simula的继承发明者们想的是这个意思:”从父母或祖先那里遗传(品质、特点或倾向)”。

从另一个对象中继承一个特征是一个很好的想法,它被称为子类型化。它完全适合面向对象编程,实际上还实现了多态性:一个Article类的对象继承了Manuscript类中的所有特征,并添加了自己的特征。例如,它继承了打印自身的能力,添加了将自身提交到会议的能力:

这就是子类型化,它是一种完美的技术;每当需要手稿时,我们可以提供一篇文章,没有人会注意到任何问题,因为类型Article是类型Manuscript的子类型(里氏替换原则)。

但是,将父类的方法和属性复制到子类中与“派生特征”有什么关系呢?实现继承就是这个意思——复制——它与我上面引用的“继承”一词的意义无关。

实现继承更接近于不同的含义:“在前任持有人死后作为继承人接收(金钱、财产或头衔)。”你问谁死了?如果一个对象允许其他对象继承它的封装代码和数据,那么这个对象就是死的。这就是实现继承:

Article 类从 Manuscript 类中 复制 了方法 print() 和属性 body,好像它不是一个有生命的有机体,而是一个我们可以继承其部分的死亡之物,”金钱、财产或头衔”。

实现继承被创建为一种代码重用的机制,它根本不适用于面向对象编程。是的,一开始它可能看起来很方便,但从对象思维的角度来看,它是完全错误的。就像获取器和设置器一样,实现继承将对象变成了带有数据和程序的容器。当然,将其中一些数据和程序复制到新对象中以避免代码重复是方便的。但这不是对象的目的。它们不是死的;它们是活的!

不要用继承来杀死它们!

因此,我认为继承是不好的,因为它是一种用于代码重用过程式技术。毫不奇怪,它引入了人们多年来一直在谈论的所有问题。因为它是过程式的!这就是为什么它不适用于面向对象编程的原因。

顺便说一下,我们在我们的 Gitter 聊天室(它已经死了)一个星期前讨论过这个问题,那时我才明确了继承的问题所在。请看一下我们在那里的讨论。

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-17 at 16:16

sixnines availability badge   GitHub stars