打字猴:1.70045483e+09
1700454830
1700454831 //父类存在的地方,子类就应该能够存在
1700454832
1700454833 Father f=new Father();
1700454834
1700454835 HashMap map=new HashMap();
1700454836
1700454837 f.doSomething(map);
1700454838
1700454839 }
1700454840
1700454841 public static void main(String[]args){
1700454842
1700454843 invoker();
1700454844
1700454845 }
1700454846
1700454847 }
1700454848
1700454849 代码运行后的结果如下所示:
1700454850
1700454851 父类被执行……
1700454852
1700454853 根据里氏替换原则,父类出现的地方子类就可以出现,我们把上面的粗体部分修改为子类,如代码清单2-14所示。
1700454854
1700454855 代码清单2-14 子类替换父类后的源代码
1700454856
1700454857 public class Client{
1700454858
1700454859 public static void invoker(){
1700454860
1700454861 //父类存在的地方,子类就应该能够存在
1700454862
1700454863 Son f=new Son();
1700454864
1700454865 HashMap map=new HashMap();
1700454866
1700454867 f.doSomething(map);
1700454868
1700454869 }
1700454870
1700454871 public static void main(String[]args){
1700454872
1700454873 invoker();
1700454874
1700454875 }
1700454876
1700454877 }
1700454878
1700454879 运行结果还是一样,看明白是怎么回事了吗?父类方法的输入参数是HashMap类型,子类的输入参数是Map类型,也就是说子类的输入参数类型的范围扩大了,子类代替父类传递到调用者中,子类的方法永远都不会被执行。这是正确的,如果你想让子类的方法运行,就必须覆写父类的方法。大家可以这样想,在一个Invoker类中关联了一个父类,调用了一个父类的方法,子类可以覆写这个方法,也可以重载这个方法,前提是要扩大这个前置条件,就是输入参数的类型宽于父类的类型覆盖范围。这样说可能比较理难理解,我们再反过来想一下,如果Father类的输入参数类型宽于子类的输入参数类型,会出现什么问题呢?会出现父类存在的地方,子类就未必可以存在,因为一旦把子类作为参数传入,调用者就很可能进入子类的方法范畴。我们把上面的例子修改一下,扩大父类的前置条件,源代码如代码清单2-15所示。
[ 上一页 ]  [ :1.70045483e+09 ]  [ 下一页 ]