里氏置换原则(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层含义:
定义一个抽象类
- publicabstractclassViewPoint{
- //去丽江旅游
- publicabstractvoidwhere();
- }
下面两个类是实现这个抽象类
classLijiangextendsViewPoint{
人物是涂涂,在里面设置类类型来传递参数。此时涂涂要去的旅游景点还是抽象的
classTutu{
场景类。设置具体要去的景点
classSence{
运行结果:
涂涂要去旅游了
欢迎来到丽江...
二、子类可以有自己的特性
父类能够存在的地方,子类就能存在,并且不会对运行结果有变动。反之则不行。
父类,say()里面的参数是HashMap类型,是Map类型的子类型。(因为子类的范围应该比父类大)
importjava.util.Collection;
子类,say()里面的参数变成了Map类型,Map范围比HashMap类型大,符合LSP原则。注意这里的say不是覆写父类的say,因为参数类型不同。而是重载。
importjava.util.Map;
importjava.util.HashMap;
父类被执行...
但是,如果将上面Father里的say参数改为Map,子类Son里的say参数改为HashMap,得到的结果就变成了
f.say(map)结果:父类被执行...
s.say(map)结果: 子类被执行...
这样会造成逻辑混乱。所以子类中方法的前置条件必须与父类中被覆写的前置条件相同或者更宽。
其实与上面的类似,也就是父类能出现的地方子类就可以出现,而且替换为子类不会产生任何错误或者异常,使用者也无需知道是父类还是子类。但是反过来就不行了,有子类出现的地方,父类未必就适应。(毕竟子类的范围要>=父类的范围)