当前位置: 首页 > news >正文

软件设计原则之LSP里氏替换原则

(LSP) 里氏替换原则 Liskov Substitution Principle

核心原则

子类必须能够替换它们的基类 (IS-A)。

场景描述

我们都知道在数学中正方形是矩形的一种特例。

我们很容易想到可以使用继承关系,即正方形作为子类继承父类矩阵。

#include <iostream> // 矩形基类 class Rectangle { private: double width = 0; double height = 0; public: virtual ~Rectangle() = default; Rectangle(double w, double h) { width = w; height = h; } void set_width(double w) { width = w; } void set_height(double h) { height = h; } double get_area() const { return width * height; }; }; // 正方形继承矩形 class Square : public Rectangle { public: Square(double len) : Rectangle(len, len) { } }; void change_oneside(Rectangle& rect, double len) { rect.set_width(len); } int main() { Square squ(10); std::cout << "Square area = " << squ.get_area() << '\n'; // 希望得到的area是400,但是最终是200 change_oneside(squ, 20); std::cout << "After set length Square area = " << squ.get_area() << '\n'; }

问题暴露

很明显,我们知道矩形可以分别修改长和宽,而正方形所有边都一样。

如果朴素的使用直接继承的设计方案,极容易出现正方形只修改一组平行边,从而退化为矩形的情况。

这就是里氏替换原则的一个经典例子,那如何解决呢?

#include <iostream> // 统一图形的接口 // 空的多态函数,让具体类型实现具体操作 class IGeometry { public: virtual void set_sideLegth(double len) { } virtual void set_sideLegth(double len1, double len2) { } virtual double get_area() const { return 0; }; }; // 矩形 class Rectangle : public IGeometry { private: double width = 0; double height = 0; public: virtual ~Rectangle() = default; Rectangle(double w, double h) { width = w; height = h; } virtual void set_sideLegth(double w, double h) override { width = w; height = h; } virtual double get_area() const override { return width * height; }; }; // 正方形 class Square : public IGeometry { private: double side = 0; public: Square(double len) { side = len; } virtual void set_sideLegth(double len) override { side = len; } virtual double get_area() const override { return side * side; }; }; void change_oneside(IGeometry& rect, double len) { rect.set_sideLegth(len); } int main() { Square squ(10); std::cout << "Square area = " << squ.get_area() << '\n'; // 希望得到的area是400,但是最终是200 change_oneside(squ, 20); std::cout << "After set length Square area = " << squ.get_area() << '\n'; }
http://www.jsqmd.com/news/794489/

相关文章:

  • PBJVision入门指南:5分钟快速搭建iOS相机应用
  • 深度解析原神帧率解锁技术:5大核心特性与源码架构实战指南
  • runtime.js设备驱动开发:深入virtio和PS2键盘实现
  • 6G无人机网络中NOMA与非线性能量采集技术解析
  • 生产环境 SQLite 数据库文件如何加密防止数据泄露
  • egg-react-ssr进阶技巧:HMR热更新与动态路由的完美结合
  • 昇腾C倒数函数API文档
  • 寝室快修|基于SprinBoot+vue的贵工程寝室快修小程序(源码+数据库+文档)
  • CANN/ops-nn THNN融合LSTM单元梯度
  • 基于深度学习cnn的打架暴力识别 YOLOv11在暴力行为识别中的应用与研究 校园暴力识别
  • 2025最权威的降AI率网站实测分析
  • LinkedOM未来展望:三重链表DOM实现的创新之路
  • 向量自旋与维度退火:组合优化新方法解析
  • 2026年上饶AI智能营销怎么选 德知域科技实力测评 - 打我的的
  • 华为CANN GE动态宽高获取API
  • tf_unet 性能调优与模型部署:实现高效推理的 3 个关键策略
  • 基于OpenTelemetry的LLM应用可观测性实践:从黑盒到透明化
  • 2026国内知名合同纠纷律师口碑排行榜单 - 品牌排行榜
  • 室内机器人深度感知故障自校准技术解析
  • retrying错误处理完全指南:异常捕获与结果过滤的终极解决方案
  • Nitrox模组扩展开发终极指南:如何为Subnautica多人联机添加新功能
  • 软件设计原则之ISP接口隔离原则
  • 跨平台光标同步工具:技术原理、实现与多屏开发效率优化
  • 3分钟解锁音乐自由:ncmdump音乐格式转换终极指南
  • 为什么SharpShooter成为红队首选?深度剖析其优势与实战价值
  • repobase:基于元数据与声明式配置的代码仓库批量管理工具
  • Cursor AI 编辑器环境配置指南:从入门到精通的自动化配置实践
  • CANN/ge ACL设置Tensor格式
  • 3步实现智能自动化:三月七小助手如何每天为你节省90分钟游戏时间?
  • CANN/asc-devkit ReduceMax API参考