跳至主要內容

里氏替换原则

微信公众号:储凡2023/11/29大约 6 分钟

里氏替换原则

里氏替换原则要求子类必须能够替换其基类,而不影响程序的正确性。换句话说,任何基类可以被其派生类无缝替换,而不会引发意外行为。 遵循该原则可以提高代码的可靠性和可扩展性。

强调子类对象必须能够替换父类对象,而程序的行为不应该发生变化。简而言之,子类对象在任何使用父类对象的地方都应该能够正常工作,而不会引发错误或不一致的行为。

举例说明

这里通过一个例子对迪米特法则进行说明。例如:

有两个类:Rectangle 和 Square。

  • Rectangle 类表示矩形,具有 width 和 height 两个受保护的属性,以及设置宽度和高度的方法 setWidth 和 setHeight 。还有一个计算面积的方法 getArea。
  • Square 类继承自 Rectangle 类,表示正方形。它重写了 setWidth 和 setHeight 方法,使得设置宽度和高度时保持相等。

定义一个 printArea 函数,用于打印矩形的面积。这个函数接受一个 Rectangle 对象作为参数,并设置宽度为 4,高度为 5,然后打印面积。

创建一个 Rectangle 对象和一个 Square 对象,并分别将它们传递给 printArea 函数进行测试。

这里体现了里氏替换原则的思想。根据里氏替换原则,子类对象(如 Square)可以替换父类对象(如 Rectangle )在任何使用父类对象的地方,而不会引发错误或不一致的行为。

printArea 函数接受一个 Rectangle 对象作为参数,可以正常地将 Square 对象传递给该函数,而不会引发错误。 尽管 Square 对象的行为略有不同(设置宽度和高度时保持相等),但仍然能够正确计算面积,并且满足父类对象的行为约定。

/**
 * 里氏替换原则Demo
 */

export class Rectangle {
  protected width: number
  protected height: number

  constructor(width: number, height: number) {
    this.width = width
    this.height = height
  }

  setWidth(width: number): void {
    this.width = width
  }

  setHeight(height: number): void {
    this.height = height
  }

  getArea(): number {
    return this.width * this.height
  }
}

export function printArea(rectangle: Rectangle): void {
  rectangle.setWidth(4)
  rectangle.setHeight(5)
  console.log(`Area: ${rectangle.getArea()}`)
}

class Square extends Rectangle {
  setWidth(width: number): void {
    this.width = width
  }

  setHeight(height: number): void {
    this.height = height
  }
}

// 使用示例
const rectangle = new Rectangle(0, 0)
const square = new Square(0, 0)

printArea(rectangle)
printArea(square)

里氏替换原则的核心思想是通过子类对象的可替换性来保证程序的正确性和稳定性。

子类应该能够完全替换父类,并且在任何使用父类的地方都能够正常工作。这样可以提高代码的可复用性和扩展性,增强系统的灵活性和可维护性。

更新日志

2025/5/18 18:01
查看所有更新日志
  • 24657-feat: 基于@142vip/vuepress对站点升级,简化配置、优化整体结构 (#234)于
  • c0f2d-refactor: 升级vuepress相关版本,优化项目结构 (#137)于
  • 6b33b-feat(ES6): 新增2016新增特性和ts文档于
  • e6a79-feat: 大幅新增设计模式、Linux命令、ORM框架教程文档于