zoukankan      html  css  js  c++  java
  • 2里氏替换原则

    里氏替换原则

    里氏替换原则的英文名称是:Liskov Substitution Principle,简称LSP(老色批)。
     

    1里氏替换原则的定义

    英文定义有两种:
    ①If for each object o1 of type S there is an object o2 of type T such thatfor all programs P defined in terms of S,the behavior of P is unchangedwhen o1 is substituted for o2 then T is a subtype of S.
    这个定义是最正宗的定义,意思是:如果对一个类型为S的对象o1,都有类型为T的对象o2,使得以S定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型T是类型S的子类型。
    ②Functions that use pointers or references to base classes must be ableto use objects of derived classes without knowing it.
    第二个定义意思是:所有引用基类的地方必须能透明地使用其子类对象。清晰明确地说明只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道父类还是子类;但是反过来则不可以,有子类的地方,父类未必就能适应。
     
     里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范
     
    继承存在很多优点,但也存在缺陷,而“里氏替换原则”可以减少"弊"所带来的麻烦
    优点:
    ■ 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;
    ■ 提高代码的可重用性;
    ■ 提高代码的可扩展性;
    ■ 提高产品或项目的开放性。
     
    缺陷:
    ■ 继承是入侵式的。只要继承,就必须拥有父类的所有属性和方法;
    ■ 降低代码的灵活性。子类必须拥有父类的属性和方法,使子类受到限制;
    ■ 增强了耦合性。当父类的常量、变量和方法修改时,必须考虑子类的修改,这种修改可能造成大片的代码需要重构。
     

    2里氏替换原则的应用

    在编译期间,java语言编辑器会检查一个程序是否符合里氏替换原则,这是一个无关实现的、纯语法意义上的检查。里氏替换原则要求是使用基类的地方,子类一定适用,因此子类必须具备基类的全部接口。或者说,子类型的接口必须包括全部的基类的接口,而且还有可能更宽。如果一个java程序破坏这一条件,java编辑器就会在编译程序时抛出错误提示,并停止编译。例如,一个基类Base声明了一个public方法改换成private或procted。
    即子类不能使用一个低访问权限的方法覆盖基类中的高访问权限的方法。
    里氏替换原则为良好的继承定义了一个规范,它包含4层含义:
    ■ 子类必须完全实现父类的方法;
    ■ 子类可以有自己的个性;
    ■ 覆盖或实现父类的方法时输入参数可以被放大;
    ■ 覆盖或实现父类的方法时输出结果可以被缩小。
    例:Animal 是一个表示动物的抽象类,只要是动物就都能动,因此提供一个抽象的move()方法;Horse和Bird都是Animal的子类。
     
    下面编写一个测试类
     1 public class Test{
     2     public static void main(String[] args){
     3         //声明一个基类对象
     4         Animal animal;
     5         //使用基类对象指向子类
     6         animal = new Horse();
     7         animal.move;
     8         animal = new Bird();
     9         animal.move;
    10         // Horse h = new Animal(); //错误
    11     }
    12 }
    View Code
    上述代码中,使用基类对象指向子类是允许的,但反过来,使用子类对象指向父类则违反里氏替换原则,会出现错误。
     
    注意按照里氏替换原则,当多个类之间存在继承关系时,通常应该使用父类或接口来指向子类的对象(除非需要使用子类特有的方法),这更利于提高系统的可扩展性。
     
    在设计模式中体现里氏替换原则的有如下几个模式:
    ■ 策略模式
    ■ 组合模式
    ■ 代理模式





    只要你不停下来,慢一点也没关系。
  • 相关阅读:
    Python进阶2.3 with的使用
    thinkswoole 跨域
    调用windows服务来监视文件夹状态
    IIS 文件名、目录名或卷标语法不正确解决方法一例
    jqgrid 动态列生成
    Oracle 术语解释 只有一部分
    招聘.NET高级软件工程师
    Zabbix监控集群操作用户“登录失败次数“和“失败日志记录“
    Gin框架组合(Zap、lumberjack、ini)使用手册
    逛书城有感
  • 原文地址:https://www.cnblogs.com/zyl-0110/p/14027130.html
Copyright © 2011-2022 走看看