设计模式:里氏替换原则(Liskov substitution principle)
里氏替换原则认为父类和子类是可互换的,即原可以使用父类的所有地方都可以使用子类进行替换。
优化前的代码
众所周知,正方形是特殊的长方形,所以在以下代码中,我们将正方形类 Square
作为长方形类 Rectangle
的子类:
class Rectangle: def __init__(self, length, width): self.length = length self.width = width def setLength(self, length): self.length = length def setWidth(self, width): self.width = width def calculateArea(self): return self.length * self.width class Square(Rectangle): def __init__(self, length, width): if length != width: raise Exception('正方形长宽必须相等') self.length = width self.width = width def setLength(self, length): self.length = length self.width = length def setWidth(self, width): self.length = width self.width = width def increase_rectangle_width(rectangle): rectangle.setWidth(rectangle.width + 1) rectangle = Rectangle(5, 5) increase_rectangle_width(rectangle) print(rectangle.calculateArea()) print('\n------子类替换父类后------\n') square = Square(5, 5) increase_rectangle_width(square) print(square.calculateArea())
但是对于上面的代码,当我们使用子类 Square
替换父类 Rectangle
后,长方形面积的计算结果和正方形的面积是不一样的,这违反了里氏替换原则。
优化后的代码
下面我们再抽象出一个四边形类 Quadrilateral
后,然后再将长方形类 Rectangle
和正方形类 Square
都继承它:
class Quadrilateral: def setWidth(self, width): pass def calculateArea(self): pass class Rectangle(Quadrilateral): def __init__(self, length, width): self.length = length self.width = width def setLength(self, length): self.length = length def setWidth(self, width): self.width = width def calculateArea(self): return self.length * self.width class Square(Quadrilateral): def __init__(self, length, width): if length != width: raise Exception('正方形长宽必须相等') self.length = width self.width = width def setWidth(self, width): self.length = width self.width = width def calculateArea(self): return self.length * self.width def increase_quadrilateral_width(quadrilateral): quadrilateral.setWidth(quadrilateral.width + 1)
此后,我们可以在其他使用 Quadrilateral
的场合下,使用子类 Rectangle
或 Square
进行代替,因为不论是长方形还是正方形,在使用抽象四边形的地方都可以进行替换,而不会影响四边形本身所要表达的含义。
参考链接
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: Python 同时遍历列表项的索引和值
下一篇: 不要相信一个熬夜的人说的每一句话
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论