里氏替换原则是面向对象设计的基本原则之一,主张使用“抽象(Abstraction)”和“多态(Polymorphism)”将设计中的静态结构改为动态结构,维持设计的封闭性。“抽象”是语言提供的功能,“多态”由继承语义实现。

里氏替换原则(Liskov Substitution Principle,LSP)由麻省理工学院计算机科学实验室的里斯科夫(Liskov)女士在 1987 年的“面向对象技术的高峰会议”(OOPSLA)上发表的一篇文章《数据抽象和层次》(Data Abstraction and Hierarchy)里提出来的,她提出:继承必须确保超类所拥有的性质在子类中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。

里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。

里氏替换原则的作用

里氏替换原则的主要作用如下。

1、里氏替换原则是实现开闭原则的重要方式之一。

2、它克服了继承中重写父类造成的可复用性变差的缺点。

3、它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。

里氏替换原则的实现方法

里氏替换原则通俗来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。

如果通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的概率会非常大。

如果程序违背了里氏替换原则,则继承类的对象在基类出现的地方会出现运行错误。这时其修正方法是:取消原来的继承关系,重新设计它们之间的关系。

关于里氏替换原则的例子,最有名的是“正方形不是长方形”。当然,生活中也有很多类似的例子,例如,企鹅、鸵鸟和几维鸟从生物学的角度来划分,它们属于鸟类;但从类的继承关系来看,由于它们不能继承“鸟”会飞的功能,所以它们不能定义成“鸟”的子类。同样,由于“气球鱼”不会游泳,所以不能定义成“鱼”的子类;“玩具炮”炸不了敌人,所以不能定义成“炮”的子类等。

下面以“几维鸟不是鸟”为例来说明里氏替换原则。

【例2】里氏替换原则在“几维鸟不是鸟”实例中的应用。

分析:鸟一般都会飞行,如燕子的飞行速度大概是每小时 120 千米。但是新西兰的几维鸟由于翅膀退化无法飞行。假如要设计一个实例,计算这两种鸟飞行 300 千米要花费的时间。显然,拿燕子来测试这段代码,结果正确,能计算出所需要的时间;但拿几维鸟来测试,结果会发生“除零异常”或是“无穷大”,明显不符合预期,其类图如图 1 所示。

程序代码如下:package principle;

public class LSPtest

{

public static void main(String[] args)

{

Bird bird1=new Swallow();

Bird bird2=new BrownKiwi();

bird1.setSpeed(120);

bird2.setSpeed(120);

System.out.println("如果飞行300公里:");

try

{

System.out.println("燕子将飞行"+bird1.getFlyTime(300)+"小时.");

System.out.println("几维鸟将飞行"+bird2.getFlyTime(300)+"小时。");

}

catch(Exception err)

{

System.out.println("发生错误了!");

}

}

}

//鸟类

class Bird

{

double flySpeed;

public void setSpeed(double speed)

{

flySpeed=speed;

}

public double getFlyTime(double distance)

{

return(distance/flySpeed);

}

}

//燕子类

class Swallow extends Bird{}

//几维鸟类

class BrownKiwi extends Bird

{

public void setSpeed(double speed)

{

flySpeed=0;

}

}

程序的运行结果如下:如果飞行300公里:

燕子将飞行2.5小时.

几维鸟将飞行Infinity小时。

程序运行错误的原因是:几维鸟类重写了鸟类的 setSpeed(double speed) 方法,这违背了里氏替换原则。正确的做法是:取消几维鸟原来的继承关系,定义鸟和几维鸟的更一般的父类,如动物类,它们都有奔跑的能力。几维鸟的飞行速度虽然为 0,但奔跑速度不为 0,可以计算出其奔跑 300 千米所要花费的时间。

其类图如图 2 所示。

更多相关知识,请访问:PHP中文网!

PHP 替换原则,里氏替换原则是什么?相关推荐

  1. 设计模式之七大原则——里氏替换原则(LSP)(三)

    里氏替换原则(Liskov Substitution Principel)是解决继承带来的问题. 4 里氏代换原则(Liskov Substitution Principle, LSP) 4.1 什么 ...

  2. 设计模式原则—里氏替换原则

    设计模式概念与作用: 设计模式是一套被反复使用的.多数人知晓.经过分类编目的优秀代码设计经验的总结.特定环境下特定问题的处理方法. 1)重用设计和代码 重用设计比重用代码更有意义,自动带来代码重用 2 ...

  3. 软件设计原则——里氏代换原则

    里氏代换原则 里氏代换原则是面向对象设计的基本原则之一. 里氏代换原则:任何基类可以出现的地方,子类一定可以出现. 通俗理解:子类可以扩展父类的功能,但不能改变父类原有的功能. 换句话说,子类继承父类 ...

  4. 面向对象五大设计原则-里氏代换原则

    1.里氏代换原则 里氏代换原则(Liskov Substitution Principle)是指,任何基类出现的地方,子类一定可以出现.反之则不一定成立. 通俗的讲便是:"老鼠儿子会打洞&q ...

  5. 【设计模式】软件设计七大原则 ( 里氏替换原则 | 定义 | 定义扩展 | 引申 | 意义 | 优点 )

    文章目录 一.里氏替换原则定义 二.里氏替换原则定义扩展 三.里氏替换原则引申意义 四.里氏替换原则意义 五.里氏替换原则优点 一.里氏替换原则定义 里氏替换原则定义 : 如果 对每一个 类型为 T1 ...

  6. 软件设计的七大原则 --开闭原则 里氏替换原则 依赖倒置原则

    在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据 7 条原则来开发程序,从而提高软件开发效率.节约软件开发成本和维护成本. 这 7 种设计原则是软件设计 ...

  7. 软件架构设计原则-里氏替换原则

    前言 里氏替换原则简单的理解可以是父类用到的地方可以用子类替换并且不改变逻辑,这就要求子类可以扩展父类的功能,但不能改变父类原有的功能.里氏替换原则要求 (1) 子类可以实现父类的抽象方法,但不能覆盖 ...

  8. 设计原则(单一职责原则 开放封闭原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特法则)

    设计原则 单一职责原则(SRP) 从三大特性角度看原则: 应用的设计模式: 开放封闭原则(OCP) 从三大特性角度看原则: 应用的设计模式: 里氏替换原则(LSP) 从三大特性角度看原则: 应用的设计 ...

  9. 设计原则——里氏替换原则

    1.全称 liskov substitution principle 缩写为:LSP 2.解释 继承必须确保超类所拥有的性质在子类中仍然成立 里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应 ...

  10. Java设计原则——里氏替换原则

    我们一定要给自己提出这样的任务:第一,学习,第二是学习,第三还是学习. 学习从来无捷径,循序渐进登高峰. 目录 一.基本介绍 二.应用实例 1.示例一 2.示例二 部分笔记来源于尚硅谷设计模式视频教学 ...

最新文章

  1. Java Script Closure(js闭包)-浅谈
  2. 软件开发过程(CMMI/RUP/XP/MSF)是与非?
  3. [Android]Activity启动过程
  4. 一个多业务、多状态、多操作的交易链路?闲鱼架构这样演进
  5. Hibernate Session get()vs load()的区别
  6. 夺命雷公狗—angularjs—11—service的基本概念
  7. 行业动态_天才、忽悠与炮灰
  8. 微星主板开机一直进入bios问题解决办法
  9. 红黑树区分 左旋 和 右旋
  10. DeepSORT的改进
  11. ceph 代码分析 读_Ceph代码分析-OSD篇
  12. 数学建模学习(47):灰色预测模型案例一(代码模板+模型建立)
  13. 系统架构师(1)计算机组成与结构
  14. c语言插值法编程,Lagrange插值的C语言编程.pdf
  15. iframe中加入html,HTML中IFRAME标签的使用
  16. 免费影视综艺动漫的手机APP(支持双端)
  17. ChatAI==ChatGPT(无需翻墙同等使用chat)
  18. 一文吃透MySQL面试八股文
  19. 作为程序员的我,常用的工具软件有这些
  20. thinkserver服务器 信号灯,IBM_X366服务器故障_指示灯介绍

热门文章

  1. PTA 游泳池改造 (30 分)
  2. 7-4 例4-3游泳池改造预算分数 10
  3. java中emit的用法_Emit用法
  4. 使用Visual Studio Code开发Java程序
  5. 【统计学 第六周】抽样分布
  6. 生成对抗式网络 GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
  7. 【ARM裸板】Nand Flash编程
  8. xlwings(python与excle交互模块)
  9. matlab数学实验分形,数学实验分形实例
  10. EMC测试(2)——电快速瞬变脉冲群抗扰度测试