阐述:子类型(subtype)必须能够替换掉它们的基类型(basetype)

先提出一个问题:正方形是不是一种特殊的长方形(IS - A关系)?

先不要回答这个问题,看下面的分析。

理解:LSP原则的一个例子,假如有个people的基类,两个字类man类和woman类,都继承于people类。那么针对people类的任何操作,比如fun吃饭、fun睡觉、fun走路,对于man类和woman类都成立。这个很好理解,不管是man还是woman,归根结底,还都是一个people。

(一)正常思维

如下例子:

class CShape
{
public:
 CShape(void);
 ~CShape(void);
public:
 virtual void Draw();
};

class CCircle:public CShape
{
public:
 CCircle(void);
 ~CCircle(void);
public:
 virtual void Draw();
};

class CSquare:public CShape
{
public:
 CSquare(void);
 ~CSquare(void);
public:
 virtual void Draw();
};

在使用CShape对象的任何地方,都可以使用CCircle对象或者CSquare对象。

(二)、特殊情况呢?

回到最初的问题,正方形是不是矩形的问题。

如下类:

class CRectangle
{
public:
 CRectangle(void);
 ~CRectangle(void);
protected:
 int  width;
 int  height;
};

class CSquare:public CRectangel
{
public:
 CSquare(void);
 ~CSquare(void);
};

假如有个函数

void g(CRectangle * r)

{

r.width = 4;

r.height = 5;

if( r.Area() != 20)

break;

}

请问,对于函数g来说,能用一个CSquare对象,代替CRectangle对象吗?很明显,不能!

很明显,违反了LSP原则。

那么,正方形到底是不似乎矩形呢?也就是说CSquare和CRectangle之间,是否存在(IS - A)关系呢?

解释:

1、从属性方面讲,正方形是矩形,是一种特殊矩形,即width = height;

2、从行为方式将,正方形可能不是矩形。

比如,对于函数g来说,描述了矩形的一种行为方式,很明显,正方形不符合这种行为方式。

OOD中的IS-A关系,是就行为方式而言的,行为方式是可以进行合理假设的。而行为方式,才是我们进行面向对象软件设计真正所关注的问题。

因此,可以讲,正方形不是一个矩形

(三)、怎么处理此类问题呢?

1、基于契约进行设计。

每个类设计时,都会有一些假设,每个方法,都有前置条件,后置条件,这些条件都是契约。对这些方法,要注明契约。

要想从基类派生子类,就必须满足这些契约。如果不满足这些契约,就不能继承出子类。(即使他们看起来很像,比如正方形与矩形)

2、但是我们又需要LSP原则,怎么办呢?

从CRectangle类和CSquare类,提取出公共部分,做为一个基类。比如CShape类。

CRectangle和CSquare都继承自CShape类。

具体一些例子,参考《敏捷软件开发》相关章节

转载于:https://www.cnblogs.com/peijihui/archive/2012/04/07/2436133.html

五大原则之----里氏替换原则(LSP)相关推荐

  1. 软件设计原则之里氏替换原则、依赖倒置原则

    系列文章目录 软件设计原则之单一职责原则.开闭原则 软件设计原则之里氏替换原则.依赖倒置原则 软件设计原则之接口隔离原则.合成复用原则.迪米特原则 文章目录 系列文章目录 一.里氏替换原则 什么是里氏 ...

  2. 七大设计原则之里氏替换原则应用

    目录 1 里氏替换原则 2 里氏替换原则应用 1 里氏替换原则 里氏替换原则(Liskov Substitution Principle,LSP)是指如果对每一个类型为 T1 的对象 o1,都有类型为 ...

  3. 6大设计原则之里氏替换原则

    面对对象中的继承 优点如下: 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性 提高代码的重用性 子类可以形如父类,但又异于父类 提高代码的可扩展性,很多开源框架的扩展接口都是通过继承父类 ...

  4. 开闭原则与里氏替换原则

    1.开闭原则 是面向对象设计的基本原则之一,是"可复用设计"的基础,它的主要原则是:对扩展开放,对修改关闭:意思就是我们改变一个软件时.应该通过扩展方式来改变软件,而不是修改原有的 ...

  5. python里氏替换原则_设计模式六大原则之里氏替换原则

    这是设计模式6 大原则系列的第二篇文章,附上前一篇文章地址:设计模式六大原则之单一职责原则.本文主要讲解设计模式的里氏替换原则. 肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.其 ...

  6. 深入理解开闭原则、里氏替换原则

    开闭原则(Open-Closed Principle)里氏替换原则 开闭原则(Open-Closed Principle) What 什么是开闭原则? Why 为什么要使用开闭原则和When 什么时候 ...

  7. 深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP

    前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http ...

  8. 【转】深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP

    前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http ...

  9. java solid设计原则_六大设计原则之里氏替换原则(LSP)

    一.SOLID 设计模式的六大原则有: Single Responsibility Principle:单一职责原则 Open Closed Principle:开闭原则 Liskov Substit ...

  10. 里氏替换原则_春辉带你了解面相对象设计第二原则(里氏替换原则)

    里氏替换原则的定义 里氏替换原则(Liskov Substitution Principle,LSP)由麻省理工学院计算机科学实验室的里斯科夫(Liskov)女士在 1987 年的"面向对象 ...

最新文章

  1. 数据库-null值和notnull操作
  2. 删除有序数组中的重复项 IIPython解法
  3. python3一个中文3个字符_高手接招! 小应用 用python3判断一个字符串是不是中文组成的...
  4. 精通 TensorFlow 1.x·翻译完成
  5. 泡面比泡MM好的16个理由
  6. convert.todatetime指定日期格式_java组件huTool日期DateUtil工具的使用
  7. sparse模式下multicast配置
  8. Mac程序开机启动项优化
  9. vb2010 java,连接用vb成功连接access2010
  10. Mybatis 大于小于符号解决
  11. vue项目路由 Navigating to current location (/xxxx) is not allowed
  12. java识别手写文字_神经网络入门 第6章 识别手写字体
  13. CAS到底是怎么回事
  14. 口袋服务器最新版,我的世界口袋版
  15. 利用EasySQLMAIL实现自动数据提取和邮件发送功能 (1)
  16. 主成分分析,聚类分析,因子分析的基本思想以及他们各自的优缺点
  17. android Setting模块简介
  18. R语言使用merge函数匹配数据(vlookup,join)
  19. 超级计算机搞笑图,搞笑图片幽默段子笑话:哥们,你的脚上下差距太大了吧,黑白分明...
  20. 云计算行业市场规模不断增加,传统制造业在“工业云”助力下完成智能升级

热门文章

  1. C语言第九次博客作业--指针
  2. MySQL数据库的datetime与timestamp
  3. linux curl模拟登录网页
  4. 查询一个表中所有id字段在另一个表中对应值的SQL语句怎么写?
  5. 解决win7“该文件没有与之关联的程序来执行该操作”
  6. 如何彻底卸载MySQL
  7. [20190805]在小程序中使用npm包
  8. 解决:设置中打开蓝牙,測试机不会自己主动搜索设备
  9. PHP常用工具方法集...
  10. python学习记录2