覆盖或实现父类的方法时输入参数可以被放大 方法中的输入参数称为前置条件,这是什么意思呢?大家做过WebService开发就应该知道有一个“契约优先”的原则,也就是先定义出WSDL接口,制定好双方的开发协议,然后再各自实现。里氏代换原则里氏替换原则也要求制定一个契约,就是父类或接口,这种设计方法也叫做DesignbyContract,契约设计,是与里氏替换原则融合在一起的。契约制定了,也就同时制定了前置条件和后置条件,前置条件就是你要让我执行,就必须满足我的条件;后置条件就是我执行完了需要反馈,标准是什么。这个比较难理解,我们来看一个例子,我们先定义个Father类,如代码清单2-11所示。
代码清单2-11 Father类源代码
1
2
3
4
5
6
7
8
9
10
11
public class Father {
public Collection doSomething(HashMap map){
System.out.println('父类被执行...');
return map.values();
}
}
这个类非常简单,就是把HashMap转换为Collection集合类型,然后再定义一个子类,源代码如代码清单2-12所示。
代码清单2-12 子类源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Son extends Father {
//放大输入参数类型
public Collection doSomething(Map map){
System.out.println('子类被执行...');
return map.values();
}
}
请注意粗体部分,与父类的方法名相同,但又不是覆写(Override)父类的方法。你加个@Override试试看,会报错的,为什么呢?方法名虽然相同,但方法的输入参数不同,就不是覆写,那这是什么呢?是重载(Overload)!不用大惊小怪的,不在一个类就不能是重载了?继承是什么意思,子类拥有父类的所有属性和方法,方法名相同,输入参数类型又不相同,当然是重载了。里氏代换原则父类和子类都已经声明了,场景类的调用如代码清单2-13所示。
代码清单2-13 场景类源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Client {
public static void invoker(){
//父类存在的地方,子类就应该能够存在
Father f = new Father();
HashMap map = new HashMap();
f.doSomething(map);
}
public static void main(String[] args) {
invoker();
}
}
代码运行后的结果如下所示:
父类被执行...
根据里氏替换原则,父类出现的地方子类就可以出现,我们把上面的粗体部分修改为子类,如下代码清单2-14所示。
代码清单2-14 子类替换父类后的源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Client {
public static void invoker(){
//父类存在的地方,子类就应该能够存在
Son f =new Son();
HashMap map = new HashMap();
f.doSomething(map);
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-21726-4.html
谢谢了
祖国呀