设计模式:里氏替换原则(Liskov substitution principle)

发布于 2025-01-27 21:52:40 字数 2620 浏览 17 评论 0

里氏替换原则认为父类和子类是可互换的,即原可以使用父类的所有地方都可以使用子类进行替换。

优化前的代码

众所周知,正方形是特殊的长方形,所以在以下代码中,我们将正方形类 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 的场合下,使用子类 RectangleSquare 进行代替,因为不论是长方形还是正方形,在使用抽象四边形的地方都可以进行替换,而不会影响四边形本身所要表达的含义。

参考链接

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

撩发小公举

暂无简介

文章
评论
26 人气
更多

推荐作者

夢野间

文章 0 评论 0

百度③文鱼

文章 0 评论 0

小草泠泠

文章 0 评论 0

zhuwenyan

文章 0 评论 0

weirdo

文章 0 评论 0

坚持沉默

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文