数码实验室 已经在面临淘汰?,面向对象程序设计大行其道几十年后( 二 )
除了该类实际上可能是另一个类的子类之外 , 因此现在还需要把父类包括在内 。 然后你意识到父类也依赖于其他类 , 并且最终包含了代码堆 。
Erlang的创建者JoeArmstrong的这句话非常著名:“面向对象编程语言的问题在于 , 它们具有随身携带的所有隐式环境 。 你想要香蕉 , 但是得到的是一只拿着香蕉的大猩猩和整个丛林 。 ”
这对此方法进行了很好的说明 。 可以重用类 , 实际上 , 这可能是面向对象编程的主要优点 。 但不要走极端 , 有时最好编写一个新类 , 而不是为了写重复代码而添加大量依赖项 。 要灵活变通 , 不要死板地遵从某个范式 。

文章图片
图源:unsplash
脆弱的基类问题
如果已经成功地将另一个项目中的类重用于新代码 , 那么基类会发生怎样的变化?
它可能会破坏整个代码 , 而你甚至可能都没有碰过它 。 也许有一天你手上的项目熠熠生辉 , 而第二天却被打回原形 , 因为有人更改了基类中的一个细微细节 , 而该细节最终对项目至关重要 。
使用继承的次数越多 , 潜在的维护工作就越多 。 因此 , 即使在短期内重用代码似乎非常有效 , 但从长远来看 , 它可能会带来很大的代价 。
钻石问题
继承是一件可爱的小事 , 可以在其中继承一类的属性并将其转移给其他类 。 但该如何组合两个不同类的属性?
这也许做不到 , 至少没办法以简洁的方式做到 , 例如Copier类 。 (笔者从CharlesScalfani的热门文章《再见 , 面向对象的编程》中借用了这个示例以及有关此处出现的问题的一些信息 。 )复印机扫描文档的内容并将其打印在空白纸上 , 它应该是Scanner还是Printer的子类?
根本没有好的答案 。 即使这个问题不会破坏代码 , 但它经常出现足以令人沮丧 。
层次问题
在钻石问题中 , 问的是Copier是哪个类的子类 。 但其实我话没说完 , 有一个简单的解决方案 。 假设Copier是父类 , 而Scanner和Printer是仅继承属性子集的子类 。
这就变得很简单 。 但如果Copier只是黑白复印 , 而Printer还可以彩色打印怎么办?从这个意义上说 , 打印机不是包括复印机的吗?如果打印机连接到WiFi但复印机没有连接怎么办?
在类上堆积的属性越多 , 建立适当的层次结构就越困难 。 确实 , 在处理属性集群时 , 其中Copier共享了Printer的部分但不是全部属性 , 反之亦然 。 而且 , 如果尝试将其置于层次结构中 , 并且是一个大型复杂项目 , 则可能会导致混乱 。 不要混淆层次结构 , 否则可能会陷入混乱 。

文章图片
图源:unsplash
参考问题
有人也许会说那么我们将进行没有层次结构的面向对象编程 。 其实相反 , 我们可以使用属性集群 , 并根据需要继承、扩展或覆盖属性 。 这会有些混乱 , 但这将是对当前问题的准确表现 。
还有一个问题 。 封装的全部目的是使数据片段彼此之间保持安全 , 从而使计算效率更高 。 没有严格的层次结构 , 这是行不通的 。
如果一个对象A通过与另一个对象B交互来覆盖层次结构 , 会发生什么?A与B的关系并不重要 , 除了B不是直接的父类 。 然后 , A必须包含对B的私有引用 , 否则 , 将无法交互 。 但是 , 如果A包含B的子代也具有的信息 , 则可以在多个位置修改该信息 。 因此 , 有关B的信息已不再安全 , 并且封装被破坏 。
尽管许多面向对象的程序员都使用这种架构来构建程序 , 但这并不是面向对象的编程 , 只是一团糟 。

文章图片
单一范式的危险
这五个问题的共同点是它们在不是最佳解决方案的地方实现了继承 。 由于继承甚至没有包含在面向对象编程的原始形式中 , 因此笔者不会将这些问题称为面向对象固有的问题 , 它们只是太过教条式的例子 。
推荐阅读
- 8K|长虹电视发起全员“作战”号召:8K时代已经全面到来
- 电影|伟大的三体舰队 已经起航!
- 腾讯|今年不新发游戏版号?腾讯张军辟谣:原博主已经销号跑路了
- 电影|还没上映 《长津湖之水门桥》已经预售入账1000万
- 数码相机|佳能EOS R5c明天发布:支持8K/60p RAW视频拍摄
- 数码相机|相机败给手机 日本佳能关闭珠海工厂:少部分零部件还在运作
- 口罩|美疾控建议戴中国标准KN95口罩 具备更好保护效应:产品价格已经飙升
- 人类|专家称第六次生物大灭绝已经开始:人类已经导致数十万物种灭绝
- 微软|微软中国第一次公开的实验室:没有KPI、上班时间惬意
- 教育未来|小学英语课本WuYifan改名WuBinbin:已经用了21年
