二、覆盖或者实现父类的方法时输入参数可以被放大
父类能够存在的地方,子类就能存在,并且不会对运行结果有变动。反之则不行。
父类,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)结果: 子类被执行……
这样会造成逻辑混乱。所以子类中方法的前置条件必须与父类中被覆写的前置条件相同或者更宽。
三、子类可以有自己的特性
也就是说在类的子类上,可以定义其他的方法或属性
四、覆写或者实现父类的方法时输出结果可以被缩小
其实与上面的类似,也就是父类能出现的地方子类就可以出现,而且替换为子类不会产生任何错误或者异常,使用者也无需知道是父类还是子类。但是反过来就不行了,有子类出现的地方,父类未必就适应。(毕竟子类的范围要》=父类的范围)