【面向对象设计原则】之里氏替换原则(LSP)
里氏代换原则由2008年图灵奖得主、美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing 教授于1994年提出,所以使用的是这位女博士的性命名的一个设计原则。
里氏替换原则(Liskov Substitution Principle, LSP):所有引用父类的地方必须能使用其子类的对象。
从这个概念可以看出这个原则是面向对象多态的一种具体实践。通俗来讲 “老爸能干的事情,儿子都能干”, 因为儿子继承了老爸的基因。 反过来讲就不对了,时代在变化,新一代虽然继承了老一代的优良传统,但是在时代的影响下,新一代有了一些新的特性,老一代可能就不具备了,比如现在的年轻人会打游戏,但是他爸不一定会。老爸会骑自行车,换成儿子也能骑。
同样的里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用父类对象。
我们定义一个父类叫Animal, 其包含一个方法叫Say如下:
public class Animal
{
private readonly string _sayContent; public Animal(string sayContent)
{
_sayContent = sayContent;
}
public virtual void Say()
{
Console.WriteLine($"Animal Say:{_sayContent}");
}
}
再定义一个子类Pig 集成自Animal,并覆盖父类中的Say 方法如下:
public class Pig:Animal
{
private readonly string _sayContent; public Pig(string sayContent) : base(sayContent)
{
_sayContent = sayContent;
} public override void Say()
{
Console.WriteLine($"Pig Say:{_sayContent}");
}
}
现在我们在调用方创建一个Animal的对象并调用Say方法:
Animal animal = new Animal("This is a parent class.");
animal.Say();
输出结果:
Animal Say:This is a parent class.
下来我们创建一个Pig对象赋给animal 对象并调用Say方法:
static void Main(string[] args)
{
Animal animal = new Animal("This is a parent class.");
animal.Say(); animal = new Pig("This is a sub class.");
animal.Say(); Console.ReadKey();
}
输出:
可以看出将子类的对象赋给父类的对象,并且得到了我们期望的结果。
里氏替换原则是实现开闭原则的重要方式之一(其实其它原则都是实现开闭原则OCP重要方式之一,上一篇【面向对象设计原则】之开闭原则(OCP) 有提及),由于使用父类对象的地方都可以使用子类对象,因此在程序中尽量使用父类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。通常我们会使用接口或者抽象方法定义基类,然后子类中实现父类的方法,并在运行时通过各种手段进行类型选择调用(比如反射)。
在使用里氏替换原则时需要注意如下几个问题:
(1)子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法。根据里氏替换原则,为了保证系统的扩展性,在程序中通常使用父类来进行定义,如果一个方法只存在子类中,在父类中不提供相应的声明,则无法在以父类定义的对象中使用该方法。
(2) 我们在运用里氏替换原则时,尽量把父类设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,运行时,子类实例替换父类实例,我们可以很方便地扩展系统的功能,同时无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。里氏替换原则是开闭原则的具体实现手段之一。这也就是我们应该更多的依赖抽象,尽量少的依赖实现细节, 其实就是我们下一篇要讲的依赖倒置原则(DIP)。
【面向对象设计原则】之里氏替换原则(LSP)的更多相关文章
- C# 实例解释面向对象编程中的里氏替换原则
在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...
- IOS设计模式的六大设计原则之里氏替换原则(LSP,Liskov Substitution Principle)
定义 里氏替换原则的定义有两种,据说是由麻省理工的一位姓里的女士所提出,因此以其名进行命名. 定义1:如果对一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1所定义的程序P中在o1全都替换 ...
- 深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP
前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http ...
- Java设计原则之里氏替换原则
里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出.其严格表述如下:如果对每一个类型为S的 ...
- 设计模式学习--面向对象的5条设计原则之Liskov替换原则--LSP
一.LSP简介(LSP--Liskov Substitution Principle): 定义:如果对于类型S的每一个对象o1,都有一个类型T的对象o2,使对于任意用类型T定义的程序P,将o2替换为o ...
- S.O.L.I.D: PHP 面向对象设计的五个基准原则
S.O.L.I.D 是首个 5 个面向对象设计 (OOD) 准则的首字母缩写,这些准则是由 Robert C. Martin 提出的,他更为人所熟知的名字是 Uncle Bob. 这些准则使得开发出易 ...
- [OOD]违反里氏替换原则的解决方案
关于OOD中的里氏替换原则,大家耳熟能祥了,不再展开,可以参考设计模式的六大设计原则之里氏替换原则.这里尝试讨论常常违反的两种形式和解决方案. 违反里氏替换原则的根源是对子类及父类关系不明确.我们在设 ...
- 【C#设计模式】里氏替换原则
今天,我们再来学习 SOLID 中的"L"对应的原则:里式替换原则. 里氏替换原则 里氏替换原则(Liskov Substitution Principle):派生类(子类)对象能 ...
- 第2章 面向对象的设计原则(SOLID):2_里氏替换原则(LSP)
2. 里氏替换原则(Liskov Substitution Principle,LSP) 2.1 定义 (1)所有使用基类的地方必须能透明地使用子类替换,而程序的行为没有任何变化(不会产生运行结果错误 ...
随机推荐
- Spring基础学习(四)—AOP
一.AOP基础 1.基本需求 需求: 日志功能,在程序执行期间记录发生的活动. ArithmeticCalculate.java public interface ArithmeticCal ...
- java 基础知识四 流程控制
java 基础知识四 流程控制 Java流程控制包括顺序控制.条件控制和循环控制 顺序控制就是逐条执行 有if和switch两个分支 循环控制就是 又称为回路控制,根据循环初始条件和终结要求,执行 ...
- Twitter数据抓取的方法(三)
Scraping Tweets Directly from Twitters Search – Update Published August 1, 2015 Sorry for my delayed ...
- ios 毛玻璃效果
推荐第三方库: https://github.com/nicklockwood/FXBlurView FXBlurView*Fx=[[FXBlurView alloc]initWithFrame:CG ...
- Python标准模块--importlib
作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 Python提供了importlib包作为标准库的一 ...
- webpack搭建服务器,随时修改刷新
前提:1.对webpack有一定了解,本文不做介绍 2.安装node.js 手把手操作: 1.创建一个名为webpack-server的文件夹(随便取的) 2.cd到当前文件夹:cd webpack- ...
- Spring Cloud搭建微服务架构----前言
前言 微服务并不神秘,只是在互联网技术发展过程中的一个产物,整个架构系统随着客户端的多样性,服务越来越多,devops的发展而产生的架构变种. 许多公司,通过采用微处理结构模式解决单体应用的问题,分解 ...
- 【渗透测试】PHPCMS9.6.0 任意文件上传漏洞+修复方案
这个漏洞是某司的一位前辈发出来的,这里只是复现一下而已. 原文地址:https://www.t00ls.net/thread-39226-1-1.html 首先我们本地搭建一个phpcms9.6.0的 ...
- 使用Express开发个人网站(一)
Express,基于Node.js平台,快速.开放.极简的 web 开发框架. Node的出现,让js有了运行在服务器端的可能,基于此的Express,可以快速,简单的搭建起一个服务器与个人网站. 安 ...
- margin重叠
margin重叠也就是我们常说的CSS 外边距合并,W3C给出如下定义: 外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距. 合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者 ...