有一本书讲到有一个PhoneNumber
类,然后我们会定义一个继承自PhoneNumber
的Address
类,然后我曾经说过,我们不能那样做,因为地址不是电话号码,要继承,它必须是"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/