上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
1.7.3 里氏替换原则
本质上,里氏替换原则(LSP)指出,如果函数可以使用指向基对象的指针或引用,那么它也可以使用指向其派生对象的指针或引用[2]。这条规则有时会被打破,因为我们在源代码中应用的技术并不总是适用于现实世界的抽象。
一个著名的例子是正方形和矩形。从数学上讲,前者是后者的特例,所以从正方形到矩形存在一种“是”的关系(正方形是矩形)。这将诱使我们创建一个继承自矩形类(Rectangle)的正方形类(Square)。所以,我们最终可能会得到像下面这样的代码:
我们应该如何实现Square类的成员呢?如果我们想遵循LSP,就会让用户对这两个类感到奇怪:如果我们调用setWidth,正方形就不再是正方形了。我们要么不使用正方形(不使用前面的代码),要么同时修改高度(调用setHeight),从而使Square类看起来与Rectangle类的行为不同。
如果代码违反了LSP,则很可能是因为使用了不正确的抽象。在我们的例子中,Square确实不应该继承自Rectangle。更好的方法可能是让Square和Rectangle都实现一个GeometricFigure接口。
既然讨论到了接口,那么我们来接着讨论与接口有关的原则。