面向对象编程会被抛弃吗?这五大问题不容忽视( 二 )
这里有一个问题:这个类可能是另一个类的子类 , 因此你需要将它的父类也包含在内 。 然后你会发现 , 这个父类可能也是另一个类的子类 , 以此类推 , 最后要面对一堆代码 。
Erlang 的创建者 Joe Armstrong 曾有一句名言:「面向对象语言的问题在于 , 它们自带其自身周围的所有隐式环境 。 你想要香蕉 , 但是得到的却是拿着香蕉的大猩猩和整个丛林 。 」
这几乎可以说明一切 。 复用类是可以的 , 实际上这可能是面向对象编程的主要优点 , 但不要将其发挥到极致 。 有时你应该建立一个新的类 , 而不是添加大量依赖项 。
文章插图
脆弱的基类问题
想象一下 , 如果你已经成功地将另一个项目中的类复用于新的代码 , 那么如果基类发生变化会怎样?
这可能会破坏你整个新项目的代码 , 即使你可能什么也没做 。 一旦有人更改了基类中的一个细节 , 而这一点又对你的项目至关重要 , 那么这种影响将是非常大并且突然的 。
使用继承的次数越多 , 潜在的维护工作就越多 。 因此 , 即使在短期内复用代码非常有效 , 但从长远来看 , 它可能让你付出一定的代价 。
菱形继承问题
利用继承可以将一类中的属性传递给其他类 。 但是 , 如果你想混合两个不同类的属性怎么办?
没错 , 这无法完成 , 至少常规的方法都不行 。 以 Copier 类为例(在此引用以下链接文章中的例子:@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53) , Copier 将扫描文件的内容并将其打印在白纸上 。 那么它应该是 Scanner 还是 Printer 的子类?
这个问题根本没有完美的答案 。 即使这个问题不会破坏你的代码 , 但它经常出现 , 会让人很沮丧 。
层级问题
在菱形继承问题中 , Copier 是哪个类的子类是问题的关键所在 。 但或许有个投机取巧的方案:假设 Copier 是父类 , Scanner 和 Printer 是仅继承属性子集的子类 , 那么问题就解决了 。
但如果你的 Copier 是黑白的 , 而 Printer 也能够处理彩色 , 那怎么办?从这个意义上说 , Printer 不是 Copier 的一种泛化吗?如果 Printer 连接了 WiFi , 而 Copier 没有呢?
类上堆积的属性越多 , 建立适当的层次结构就越困难 。 在你所处理的属性集群中 , Copier 共享了 Printer 的一些属性 , 但不是全部属性 , 反之亦然 。 在大型复杂项目中 , 层次结构的问题会导致很大的混乱 。
文章插图
引用问题
你可能会想到进行没有层次结构的面向对象编程 。 我们可以使用属性集群 , 并根据需要继承、扩展或重写属性 。 也许这有点混乱 , 但这将是对当前问题的准确表示 。
这里只存在一个问题:封装的全部目的是使数据片段彼此之间保持安全 , 从而使计算效率更高 , 但没有严格的层次结构 , 这是行不通的 。
【面向对象编程会被抛弃吗?这五大问题不容忽视】假设一个对象 A 通过与另一个对象 B 交互来覆盖层次结构 , 会发生什么情况?其他关系的情况并不重要 , 但当 B 不是 A 的直接父类时 , A 必须包含 B 的全部私有引用 , 否则 , 它们将无法交互 。
但是 , 如果 A 包含 B 的子类也具有的信息 , 那么就可以在多个位置修改该信息 。 因此 , 有关 B 的信息已经不再安全 , 并且封装已经被破坏 。
尽管许多面向对象的程序员都使用这种架构来构建程序 , 但这并不是面向对象编程 , 只是一团糟 。
单一范式存在的风险
以上 5 个问题的共同点是它们都存在不合适的继承 。 由于继承没有包含在面向对象编程的原始形式中 , 所以这些问题可能不能称为面向对象本身的问题 。
- 机器人|万州区举办“中国梦科技梦”机器人编程大赛
- 小米11评测:首发骁龙888 面向新10年的启航之作
- 英特尔推出可检测代码错误的ControlFlag机器编程工具
- 可编程3D打印耗材可帮助普通3D打印机轻松实现多材料物品的制作
- F2FS面向Linux 5.11继续加强其加密及文件数据压缩功能
- 微信推出收费服务,面向12亿用户!看完你还想更新微信吗?
- 面向普通用户!冷门品牌逆袭之路,性能和续航哪个更重要?
- 菜鸟学编程,不懂C++ this指针?还不赶快来学一学
- 大学生如何提升Java编程能力
- 对于一个编程小白来说,该学习Java还是Python