oop - 如果 Address 继承自 PhoneNumber,它违反了哪些 OOP 原则?

标签 oop object-oriented-analysis liskov-substitution-principle

有一本书讲到有一个PhoneNumber类,然后我们会定义一个继承自PhoneNumberAddress类,然后我曾经说过,我们不能那样做,因为地址不是电话号码,要继承,它必须是"is"的关系。如:狗是一种动物,我们可以让Dog继承自Animal

但是因为我们必须遵循LSP -- Liskov Substitution Principle ,那么"is"规则实际上不是这里的决定因素,因为正方形"is"矩形(宽度 == 高度),但 LSP 说我们不能定义 Square 类并继承自 Rectangle 类。我认为英文的简单解释是对象 aRect 可以响应消息 setWidthAndHeight(w, h),但是 aSquare 不能'不要正确响应它并让整个程序正确运行。

令人惊讶的是,继承PhoneNumber 类的Address 类违反了“is a”关系,但并未违反LSP。那么正式地,它违反了哪些 OOP 原则?

最佳答案

首先,这确实确实违反了 LSP。

通常,您不会期望能够用地址代替电话号码。这是每个人都在评论中谈论的“常识”。

OOP 理论的要点是,遵循正式规则将使您的类变得健壮,以适应变化和奇怪的用例等事情。即使书中的示例实际上并未违反 LSP,我想如果您尝试扩展该类架构,它也会很快崩溃。因此,为了避免在未来的类(class)中出现潜在错误,您应该遵循 LSP - 即使选择不这样做也不会立即破坏任何东西。

其次,它违反了ISP(接口(interface)隔离原则)。

这表明类中可用的方法集应该是类对象运行所需的最小值

如果 Address 类继承(或可能合理地继承)一堆在处理实际街道地址时从未使用过的 PhoneNumber 方法(例如 getAreaCode() 方法,对于房屋地址将是未定义的),那么它的接口(interface)不是最小的。

要点是 OOP 原则实际上只是指南。绝对有可能编写违反 SOLID 原则但实际上不会引入错误的奇怪示例代码。这并不意味着你在绕过规则。这只是意味着一旦您尝试扩展该类,您就会遇到更多错误。

关于oop - 如果 Address 继承自 PhoneNumber,它违反了哪些 OOP 原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15049376/

相关文章:

c++ - 如何实现嵌套流畅的接口(interface)?

java : How do you create a function that increments a variable that isn't accessible from outside the function?

php - 公共(public)属性无法访问面向对象的 PHP

oop - 省略 super() 和/或 *weakening* 前提条件是否违反里氏替换原则?

c# - Liskov 替换和合成

java - 在Java中查找调用方法的类的类型

Python面向对象: how to stop procedure flow in an entire class with `return` statement?

PHP, OOP, 静态

java - 对派生类中的成员变量使用派生类型

c# - Liskov 替换原则与普通继承有何不同?