【设计模式】里氏代换

原创 2015年10月03日 17:22:52

       里氏代换原则由2008年图灵奖得主、美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出的。

示例

为了说明里氏代换是基于一种什么情况而提出的,我们先看这么一个问题。

public class A {

 public int Add(int a,int b)
 {
     return a+b;
 }
    
}

public class Client {
    public static void main(String[] args){
    A a=new A();
    System.out.print("20+30="+a.Add(20,30));
    }
}

运行结果: 20+30=50


在上面的示例中,定义了一个类A,实现了一个加法算法,客户端调用该算法,并打印结果。

现在因为需求的变化,要增加一个功能,由一个新的类B来完成(类B要实现该加法功能,同时还要再添加一个新的功能).

然后采取了这样一种解决方案:因为类A已经实现了一个功能,所以由类B去继承A,然后在去完成第二个功能.


看采取了这种解决方案的算法:

public class B extends A{
  
   public int Add(int a,int b)
 {
     return a-b;
 }
   public void fun(int a)
   {
       System.out.print("你输入的数是"+ a);
   }
}

public class Client {
    public static void main(String[] args){
        A a=new A();//实例化A
    B b=new B();//实例化B
     System.out.println("20+30="+a.Add(20,30));//调用A 的方法
    System.out.println("20+30="+b.Add(20,30));//调用B的方法
    b.fun(20);
    }
}

运算结果:

20+30=50

20+30=-10

       我们会发现当我们使用类B的加法算法的时候我们确得到了一个减法的结果。类A原本正常的功能,因为在B继承后无意识的重写导致原本正常的功能出现了错误。

里氏代换

      

        如果你曾经写过这样的代码,那么你就违背了里氏代换原则.

       里氏代换主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中所包含的一些原理。

        里氏代换(LSP)可以这样理解:子类可以扩展父类的功能,但不能改变父类的原有功能.或者说任何基类可以出现的地方,子类一定可以出现,反过来是不成立的 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对-原则的补充。实现-原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

         需要注意的是里氏代换是一种规范,就好像我们国家的官方语言是普通话,但是我们的生活中基本上不说普通话,同样的道理,不使用这个原则我们的代码一样可以跑的好好的,但是不可回避的是不遵守这个原则确实会增加出错的几率.


         里氏代换包含以下4层含义:
  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

更合理的解决方案

    LSP是关于父类和子类的关系。只有当这种关系存在时,里氏代换关系才存在,如果两个具体的类A,B之间的关系违反了LSP的设计,那个根据具体的情况我们可以在采用如下两种方法进行重构。
       1.创建一个抽象类C,作为两个具体类的超类,将A,B的共同行为移动到C中来解决
       2.从B到A的继承关系改为委派关系。
      
      当我们决定使用继承的时候如果子类不能完整的实现父类的方法,或者父类的某些方法在子类中已经发生了变化,这是我们就要考虑断开父子关系,采用依赖,聚集或组合等关系代替继承。
     

总结

     里氏代换原则是很多设计模式的基础,我们都知道设计模式都是一定程度上遵循开放封闭原则,里氏代换原则和开放封闭原则的联系尤其紧密,违背了里氏代换原则就一定不符合开放封闭原则,因为里氏代换原则是实现开放封闭原则的具体规范。


版权声明:那些你不愿意做的事情才能让你真正成长

大话设计模式学习笔记(3,4,5)----单一职责,开放-封闭,依赖倒转,里氏代换原则

由于第3,4,5章讲的是设计模式里面的几个原则,没有讲具体的设计模式,所以我这里就把这三章放在一起写了。不过虽然篇幅短但是由于是原则,这些可是非常重要的。原则性的东西一只手都能数的过来,但是想要完全搞...

java设计模式_里氏代换原则

一、什么是里氏代换原则里氏代换原则(Liskov Substitution Principle): 一个软件实体如果使用的是一个父类的话,那 么一定适用于其子类,而且它察觉不出父类和子 ...

大话设计模式05----依赖倒转原则 & 里氏代换原则

(1)依赖倒转原则(强内聚,低耦合): 高层模块不应该依赖低层模块。两个都应该依赖抽象。抽象不应该依赖细节。细节应该依赖抽象【ASD】。----也就是说要指针接口编程,不要对实现编程。 (2)里氏...

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

里氏代换原则(Liskov Substitution Principle) 里氏代换原则是由麻省理工学院(MIT)计算机科学实验室的Liskov女士,在1987年的OOPSLA大会上发表的一篇文章《...

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

Functions that use pointers or referencesto base classesmust be able to use objects of derived class...

设计模式六大原则-单一职责原则、开放封闭原则、依赖倒转原则、里氏代换原则、迪米特法则、合成/聚合复用原则

原则,故名思议则是本质的意思。所谓擒贼先擒王,研究设计模式自然要先了解设计原则,所有的模式都是在这些原则的基础之上发展起来的,有的是侧重一个,有的是多个都有所涉及。看完设计模式之后,我感觉到每个模式都...

android设计模式之里氏代换原则(LSP)

里氏代换原则(LiskovSubstitution Principle,常缩写为LSP)。里氏代换原则由Barbara Liskov提出。...

【有毒的设计模式】单一指责原则、开放-封闭原则、依赖倒转原则、里氏代换原则

单一指责原则、开放-封闭原则、依赖倒转原则、里氏代换原则

单一职责原则+开放-封闭原则+依赖倒转原则+里氏代换原则【设计模式】【学习总结】

面向对象设计中的各种原则: 单一职责原则SRP 开放-封闭原则OCP 依赖倒转原则 里氏代换原则LSP...

设计模式六大原则——里氏代换原则(LSP,Liskov Substitution Principle)

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【设计模式】里氏代换
举报原因:
原因补充:

(最多只允许输入30个字)