设计模式六大原则——里氏替换原则(LSP)

       概述

       里氏替换原则(LSP,Liskov Substitution Principle)是关于继承机制的原则,是实现开放封闭原则的具体规范,违反了里氏替换原则必然违反了开放封闭原则。

   

   引经据典

                  

   

约瑟夫.斯大林,苏联时期苏联共产党的最高领导人,对于斯大林有没有替身?有几个替身?有一种说法:斯大林有好几个替身,最著名的当属“第一替身”叶夫谢伊.卢比茨基——他“扮演”领袖斯大林长达15年之久,很多高官都被蒙在鼓里。

斯大林作为一国的领导人,肯定要不停的参加各种的聚会,进行各中慰问。。。找几个替身,忙里偷闲或者外出打掩护......

                                                                         

子类必须完全实现父类的方法

替身代替斯大林去参加各种活动时,他的相貌和一举一动都必须和真的斯大林一模一样,毕竟斯大林代表的是一个国家,如果让别人发现来见自己的是个替身,那不就让人寒心了嘛... 看一下代码:

//斯大林
    public class SiDaLin
    {
        //斯大林讲话行为
        public virtual void SpeakWay()
        {
            Console .WriteLine ("右手举过头顶、伸出两个手指、不断前后摆动,以表示强调或愤慨。")
        }
    }
    //替身
    public class TiShen : SiDaLin
    {
        //替身的讲话行为
        public override void SpeakWay()
        {
            Console .WriteLine ("右手举过头顶、伸出两个手指、不断前后摆动,以表示强调或愤慨。")
        }
    }

           不知道大家有没有注意到上面代码中父类中的virtual和子类中的override,为什么要用到它们?

在继承关系中,子类对父类的继承除了字段、属性,还有方法,而使同一方法在子类中表现出不同的行为是通过多态表现的,具体在语言上的操作上表现为父类提供虚函数,而在子类中覆写该虚函数,这是抽象机制的重要基础。

public static void DoSomething(Fatherclass f)
        {
            f.Method();
        }

   如果Method被实现为虚函数,并且在子类中被覆写,那么传入DoSomething中的实参既可以是父类,也可以是子类,子类完全可以替代父类在此调用自己的方法,这正是里氏替换原则强调的继承关系,代码如下:

class Fatherclass
    {
        //父类行为
        public virtual void Method()
        {
        }
    }
    class Sonclass :Fatherclass
    {
        //子类重写父类方法
        public override void Method()
        {
        }
    }

(上面这个问题的回答参考《你必须知道的.NET》)

子类可以有自己的“个性”

采用里氏替换原则时,尽量避免子类的“个性”,一旦子类有“个性”,这个子类和父类之间的关系就很难调和了,把子类当做父类使用,子类的“个性”被抹杀——委屈了点;把子类单独作为一个业务来使用,则会让代码间的耦合关系变得扑朔迷离——缺乏类替换的标准。

 就拿斯大林的替身来说,每一个替身都是一个人,都有自己的“个性”,但是他们是斯大林的替身,那么他们平时的表现就必须按照斯大林的表现来,如果他们加入自己的“个性”,那么他们替身的身份就会漏出破绽。

 

结论

实现开闭原则的关键步骤是抽象化,父类与子类之间的继承关系就是抽象化的体现,因此里氏替换原则是实现开闭原则的具体步骤规范,违反里氏替换原则一定违反开闭原则,反之未必。

   

   

时间: 2024-10-25 14:13:18

设计模式六大原则——里氏替换原则(LSP)的相关文章

举例解析Java的设计模式编程中里氏替换原则的意义_java

里氏替换原则,OCP作为OO的高层原则,主张使用"抽象(Abstraction)"和"多态(Polymorphism)"将设计中的静态结构改为动态结构,维持设计的封闭性."抽象"是语言提供的功能."多态"由继承语义实现. 里氏替换原则包含以下4层含义: 子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法. 子类中可以增加自己特有的方法. 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更

设计模式六大原则 里氏替换原则

设计模式六大原则(2):里氏替换原则 是不是有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 2002年,软件工程大师Robert C. Martin,出版了一本<Agile Software Development Principles Patterns and Practices>,在文中他把里氏代换原则最终简化为一句话: "Subtypes must b

设计模式之禅之六大设计原则-里氏替换原则

里氏替换原则说的就是面向对象语言的继承--->代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性.--->提高代码的重用性.--->子类可以形似父类,但又特殊于父类.--->提高代码的可扩展性.实现父类的方法,可以为所欲为.许多开源框架的接口都是继承父类完成的.--->提高产品或项目的开放性.--->继承是侵入性的.子类必须拥有父类的属性和方法.让子类自由的世界中多了些约束.--->增强了耦合性.当父类的常量,变量和方法被修改时,需要考虑子类的修改.造成

设计模式学习:里氏替换原则

这节中我们会聊聊里氏替换原则,聊它之前,我们先看看定义. 定义:如果对每一个类型为T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型.(摘自java与模式一书) 如果你觉得定义说的模糊了点,不太清楚,没关系,我们慢慢说明白.里氏替换原则的另一个简短的定义是"所有引用基类的地方必须能透明地使用其子类的对象".这个可能更清楚点.如果你熟悉的掌握一门面向对

设计模式六大原则(2):里氏替换原则

肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型. 定义2:所有引用基类的地方必须能透明地使用其子类的对象. 问题由来:有一功能P1,由类A完成.现需

[OOD]违反里氏替换原则的解决方案

关于OOD中的里氏替换原则,大家耳熟能祥了,不再展开,可以参考设计模式的六大设计原则之里氏替换原则.这里尝试讨论常常违反的两种形式和解决方案. 违反里氏替换原则的根源是对子类及父类关系不明确.我们在设计继承关系常常受一些主观认识的左右,比如Robert C. Martin提到的线段与线的关系,以及被大家说到烂的正方形与矩形.从以前的经验我们认为它们符合继承关系,比如线段是线的较短形式,正方形是矩形的一个特例.但事实上它们并不能完全的包容和替代. 以集合的形式表示,左图是里氏替换的目标,子类可以完

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

前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http://freshbrewedcode.com/derekgreer/2011/12/31/solid-javascript-the-liskov-substitution-principle/ 复制代码 开闭原则的描述是: Subtypes must be substitutable for the

设计模式六大原则--里氏代换原则

       背景        上一篇我总结了一下依赖倒转原则,查了很多资料发现凡总结依赖倒转原则的时候,大多数人也会把里氏代换原则顺道也给总结了.Why?还是让我们先来看看里氏代换原则(Liskov Substitution Principle, LSP)吧.        定义        Functions that use pointers or referencesto base classesmust be able to use objects of derived class

java设计模式六大原则之场景应用分析

看了一篇文章,感觉收获蛮大,不过还有一些不懂,收藏慢慢研究. 面对项目中如此众多的设计模式,我们有时候无法下手.在强大的设计框架也终脱离不了23种设计模式,6大原则.我们只要把内功修炼好,掌握其精髓也离我们不远了...     目录: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大原则(6):开闭原则 设计模式六大原则(1):单一职责原则 设计