里氏替换原则_春辉带你了解面相对象设计第二原则(里氏替换原则)
里氏替换原则的定义
里氏替换原则(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)。里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。
里氏替换原则的作用
里氏替换原则的主要作用如下。
里氏替换原则是实现开闭原则的重要方式之一。
它克服了继承中重写父类造成的可复用性变差的缺点。
它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
里氏替换原则的实现方法
里氏替换原则通俗来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。如果通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,程序运行出错的概率会非常大。如果程序违背了里氏替换原则,则继承类的对象在基类出现的地方会出现运行错误。这时其修正方法是:取消原来的继承关系,重新设计它们之间的关系。关于里氏替换原则的例子,最有名的是“正方形不是长方形”。当然,生活中也有很多类似的例子,例如,企鹅、鸵鸟和几维鸟从生物学的角度来划分,它们属于鸟类;但从类的继承关系来看,由于它们不能继承“鸟”会飞的功能,所以它们不能定义成“鸟”的子类。同样,由于“气球鱼”不会游泳,所以不能定义成“鱼”的子类;“玩具炮”炸不了敌人,所以不能定义成“炮”的子类等。下面以“几维鸟不是鸟”为例来说明里氏替换原则。【例2】里氏替换原则在“几维鸟不是鸟”实例中的应用。分析:鸟一般都会飞行,如燕子的飞行速度大概是每小时 120 千米。但是新西兰的几维鸟由于翅膀退化无法飞行。假如要设计一个实例,计算这两种鸟飞行 300 千米要花费的时间。显然,拿燕子来测试这段代码,结果正确,能计算出所需要的时间;但拿几维鸟来测试,结果会发生“除零异常”或是“无穷大”,明显不符合预期,其类图如图 1 所示。
图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 所示。
图2 “几维鸟是动物”实例的类图
里氏替换原则_春辉带你了解面相对象设计第二原则(里氏替换原则)相关推荐
- python三大特征六大原则_面向对象程序设计(Object Oriented Programming)的三大特性,六大原则...
三大特性 封装.继承.多态性 拿简单工厂模式举例: namespace DesignMode_01 { // 计算基类 public class Operation { private double ...
- 最大隶属度原则_模糊数学笔记:六、模糊模型识别-I(最大隶属度原则)
1.模型识别的问题提出 模型识别,通俗地理解即是对一个类别未知的对象进行归类(或者叫分类).这里与聚类不同的是,聚类实际上是要区分出已有的样本哪些属于同一类,但并没有参考标准.而识别则事先有参考的标准 ...
- 举例说明层次分析的三大原则_《搞定》一个境界、两个维度、三大原则让你轻松搞定繁重的事务...
文/定石 不知道,你现在是不是还是这种情况,要做的事情一大堆,单位的事情要忙,家里的事情要忙,孩子的事情要忙,父母的事情要忙.各种各样的事情,好像都急,干着这个,想着那个,另一个还放在心上不踏实,整体 ...
- java solid设计原则_六大设计原则之里氏替换原则(LSP)
一.SOLID 设计模式的六大原则有: Single Responsibility Principle:单一职责原则 Open Closed Principle:开闭原则 Liskov Substit ...
- 面象对象设计6大原则之三:里氏替换原则
转载自 面象对象设计6大原则之三:里氏替换原则 里氏替换原则(LSP),The Liskov Substitution Principle 定义 所有引用基类的地方必须能透明地引用其子类的对象,即子类 ...
- 注释标记的原则_它关系到平台如何标记操纵的媒体。 这是设计师应遵循的12条原则。
注释标记的原则 By Emily Saltz, Tommy Shane, Victoria Kwan, Claire Leibowicz, Claire Wardle 埃米莉·萨尔茨 ( Emily ...
- uml 时序图_设计模式:UML是怎么回事?设计原则?
设计模式:UML是怎么回事?设计原则? 还未毕业,想着至少大学毕业前,设计模式多多了解,所以做相关笔记. UML相关概念 UML(Unified 统一 Modeling 建模 Language 语言) ...
- java 设计原则_【无尽的编程之路】(java)-设计模式六大原则
本文主内容主要是列出各项原则的定义与本人对六大原则的感悟.写出来的目是想与大家分享与讨论.正如有句话叫做一千个读者眼中有一千个哈姆雷特,如果大家对这六项原则的理解跟我有所不同,欢迎留言,大家共同探讨. ...
- 设计模式六大原则_设计模式—设计六大原则
1. 单一职责原则(SRP) 定义:就一个类而言,应该仅有一个引起它变化的原因. 从这句定义我们很难理解它的含义,通俗讲就是我们不要让一个类承担过多的职责.如果一个类承担的职责过多,就等于把这些职责耦 ...
最新文章
- 单片机节日彩灯实训报告_单片机课程设计(节日彩灯控制)
- 主流大数据系统在后台的层次角色及数据流向
- 以太坊再爆高危漏洞!黑客增发ATN 1100万枚token事件始末
- 650c公路车推荐_盘点2020年各价位高性价比入门公路车
- wampserver3.2.0_MySQL 8.0 技术详解
- 记一次机房断电办公室网络瘫痪的恢复经过
- 联想官方OEM分区制作
- 新媒体运营黎想教程:活动运营策划的简略4个方式
- 全面了解Qtum节点端口配置,立即加入全节点激励计划
- 【NS3】NS3安装 visualizer模块安装 (Windows+VMware+Kali) 2022.2
- MJ“点击或上拉加载更多”问题
- Tensorflow和Keras基础使用教程
- JDK1.9-缓冲流
- 清华计算机博士蓝宴翔的工作是,毕啸天:清华博士玩成“科研段子手”
- 《写给大家看的设计书(第4版)》读书笔记
- CSS的基本概念———每天一遍小知识
- 获取固有节假日的时间戳数组 (美国节假日)
- 如何在iOS上实现苹果电脑最小化窗口时的“神奇效果”(即吸入吸出效果在iPhone上的实现)
- 计算机组成原理——操作数寻址方式
- libminimsgbus集成消息通讯库(多协议订阅发布)
热门文章
- python工程师干什么的_Python就业前景和工资待遇分析,你学Python了吗?
- CentOs下部署Core环境
- CSS3属性——“box-flex”
- HiHocoder 1036 : Trie图 AC自动机
- 一个基于DataTable的后台框架的实现
- Android SDK Setup如何使用?
- linux设备驱动之PCIE驱动开发
- VS2019 + Qt ERROR MSB4181 QtRunwork 返回了false,但未记录错误
- webRTC之智能指针std::unique_ptr::reset()使用(十四)
- 机器学习入门(三):神经网络起手式