1700454780
1700454781
}
1700454782
1700454783
}
1700454784
1700454785
显示是不行的,会在运行期抛出java.lang.ClassCastException异常,这也是大家经常说的向下转型(downcast)是不安全的,从里氏替换原则来看,就是有子类出现的地方父类未必就可以出现。
1700454786
1700454787
3.覆盖或实现父类的方法时输入参数可以被放大
1700454788
1700454789
方法中的输入参数称为前置条件,这是什么意思呢?大家做过Web Service开发就应该知道有一个“契约优先”的原则,也就是先定义出WSDL接口,制定好双方的开发协议,然后再各自实现。里氏替换原则也要求制定一个契约,就是父类或接口,这种设计方法也叫做Design by Contract(契约设计),与里氏替换原则有着异曲同工之妙。契约制定了,也就同时制定了前置条件和后置条件,前置条件就是你要让我执行,就必须满足我的条件;后置条件就是我执行完了需要反馈,标准是什么。这个比较难理解,我们来看一个例子,我们先定义一个Father类,如代码清单2-11所示。
1700454790
1700454791
代码清单2-11 Father类源代码
1700454792
1700454793
public class Father{
1700454794
1700454795
public Collection doSomething(HashMap map){
1700454796
1700454797
System.out.println(“父类被执行……”);
1700454798
1700454799
return map.values();
1700454800
1700454801
}
1700454802
1700454803
}
1700454804
1700454805
这个类非常简单,就是把HashMap转换为Collection集合类型,然后再定义一个子类,源代码如代码清单2-12所示。
1700454806
1700454807
代码清单2-12 子类源代码
1700454808
1700454809
public class Son extends Father{
1700454810
1700454811
//放大输入参数类型
1700454812
1700454813
public Collection doSomething(Map map){
1700454814
1700454815
System.out.println(“子类被执行……”);
1700454816
1700454817
return map.values();
1700454818
1700454819
}
1700454820
1700454821
}
1700454822
1700454823
请注意粗体部分,与父类的方法名相同,但又不是覆写(Override)父类的方法。你加个@Override试试看,会报错的,为什么呢?方法名虽然相同,但方法的输入参数不同,就不是覆写,那这是什么呢?是重载(Overload)!不用大惊小怪的,不在一个类就不能是重载了?继承是什么意思,子类拥有父类的所有属性和方法,方法名相同,输入参数类型又不相同,当然是重载了。父类和子类都已经声明了,场景类的调用如代码清单2-13所示。
1700454824
1700454825
代码清单2-13 场景类源代码
1700454826
1700454827
public class Client{
1700454828
1700454829
public static void invoker(){
[
上一页 ]
[ :1.70045478e+09 ]
[
下一页 ]