设计模式--6大原则--里氏置换原则

转载 2012年03月31日 16:34:33

里氏置换原则(Liskov Substitution Principle),简称LSP

定义:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

所有引用基类的地方必须能够透明的使用其子类对象。

也就是说,只要父类出现的地方子类就能够出现,而且替换为子类不会产生任何错误或异常。但是反过来,子类出现的地方,替换为父类就可能出现问题了。

这个原则是为良好的继承定义一个规范,简单的讲,有4层含义:

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

定义一个抽象类

public abstract class ViewPoint {
    //去丽江旅游
    public abstract void where();
}

下面两个类是实现这个抽象类

public class Lijiang extends ViewPoint {
  
    @Override
    public void where() {
        System.out.println("欢迎来到丽江...");
    }
  
}
public class Zhangjiajie extends ViewPoint {
  
    @Override
    public void where() {
        System.out.println("欢迎来到张家界...");
    }
  
}

人物是涂涂,在里面设置类类型来传递参数。此时涂涂要去的旅游景点还是抽象的

public class Tutu {
    //定义要旅游的景点
    private ViewPoint viewpoint;
    //涂涂要去的景点
    public void setViewPoint(ViewPoint viewpoint)
    {
        this.viewpoint = viewpoint;
    }
      
    public void travelTo()
    {
        System.out.println("涂涂要去旅游了");
        viewpoint.where();
    }
}

场景类。设置具体要去的景点

public class Sence {
    public static void main(String args[])
    {
        Tutu tutu = new Tutu();
        //设置要去的旅游景点
        tutu.setViewPoint(new Lijiang());
        tutu.travelTo();
    }
}

运行结果:

涂涂要去旅游了
欢迎来到丽江...

二、子类可以有自己的特性

也就是说在类的子类上,可以定义其他的方法或属性

三、覆盖或者实现父类的方法时输入参数可以被放大

父类能够存在的地方,子类就能存在,并且不会对运行结果有变动。反之则不行。

父类,say()里面的参数是HashMap类型,是Map类型的子类型。(因为子类的范围应该比父类大)

import java.util.Collection;
import java.util.HashMap;
  
public class Father {
    public Collection say(HashMap map)
    {
        System.out.println("父类被执行...");
        return map.values();
    }
}

子类,say()里面的参数变成了Map类型,Map范围比HashMap类型大,符合LSP原则。注意这里的say不是覆写父类的say,因为参数类型不同。而是重载。

import java.util.Collection;
import java.util.Map;
  
/*
 * 子类继承了父类的所有属性
 */
public class Son extends Father {
    //方法输入参数类型
    public Collection say(Map map)
    {
        System.out.println("子类被执行...");
        return map.values();
    }
}

场景类

import java.util.HashMap;
  
public class Home {
    public static void main(String args[])
    {
        invoke();
    }
      
    public static void invoke()
    {
        //父类存在的地方,子类就应该能够存在
        //Father f = new Father();
        Son s = new Son();
        HashMap map = new HashMap();
        //f.say(map);
        s.say(map);
    }
}

无论是用父类还是子类调用say方法,得到的结果都是

父类被执行...

但是,如果将上面Father里的say参数改为Map,子类Son里的say参数改为HashMap,得到的结果就变成了

f.say(map)结果:父类被执行...
s.say(map)结果: 子类被执行...

这样会造成逻辑混乱。所以子类中方法的前置条件必须与父类中被覆写的前置条件相同或者更宽。

四、覆写或者实现父类的方法时输出结果可以被缩小

其实与上面的类似,也就是父类能出现的地方子类就可以出现,而且替换为子类不会产生任何错误或者异常,使用者也无需知道是父类还是子类。但是反过来就不行了,有子类出现的地方,父类未必就适应。(毕竟子类的范围要>=父类的范围)

相关文章推荐

设计模式6大原则:里氏置换原则

里氏置换原则(Liskov Substitution Principle),简称LSP 定义: Functions that use pointers or references to b...

设计模式--6大原则--里氏置换原则

里氏置换原则(Liskov Substitution Principle),简称LSP 定义: Functions that use pointers or references to base ...

设计模式七大原则之里氏置换原则

里氏置换原则 里氏置换原则的两种定义:定义一: 如果对于每一个类型是s的对象o1,都有类型为T的对象o2,使得用T定义的所有程序P在所有对象o1都代换成o2时, 程序p并没有什么变化,那么S就是...

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

LSP里氏替换原则:其子类对象可以代替父类对象,但其父类对象不能代替子类对象.OCP作为OO的高层原则,主张使用“抽象”和“多态”将设计中的静态结构改为动态结构,维持设计的封闭性。 “抽象”是语言提...

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

里氏替换原则 里氏替换原则:Liskov Substitution Principle(LSP) 刚看到这项原则的时候很困惑,完全不懂什么意思,不过根据西方人思维,喜欢用人名来命名,以纪念或彰显某个人...

设计模式6大原则之里氏替换原则

里氏替换原则 定义: 所有引用基类的地方必须能透明地使用其子类的对象。 通俗点讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类...

java设计模式—里氏置换原则(LSP)

一、定义 里氏置换原则(Liskov Substitution Principle),简称LSP Functions that use pointers or references to base ...

设计模式6大原则

  • 2012-03-03 11:26
  • 239KB
  • 下载

设计模式6大原则

  • 2012-03-04 20:56
  • 239KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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