java设计模式之里氏替换原则(LSP)
里氏替换原则
If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged where o1 is substituted for o2 then S is a subtype of T。(Functions that use pointers or references to base classes must be able to use object of derived classes without knowing it)
如果对每一个类型S的对象O1,都有类型为T的对象O2,使得以T定义的所有程序P在所有的对象O1都代换成O2时程序P的行为没有发生变化,那么S是T的子类型。
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
所有应用子类型的地方必须透明地使用其子类型的对象。
规则:1.子类必须完全实现父类的方法
2.子类可以有自己的个性
3.覆盖或实现父类的方法时输入参数可以被放大
1 package com.test.pattern;
2
3
4 public class LSP {
5
6 public static void main(String[] args) {
7 Father f = new Son();
8 Son s = new Son();
9 f.reduction("reduction");
10 s.reduction("reduction");
11
12 f.enlarge("enlarge");
13 s.enlarge("enlarge");
14 }
15
16 }
17
18 class Father{
19
20 public void reduction(CharSequence seq){
21 System.out.println("father : " + seq);
22 }
23
24 public void enlarge(String str){
25 System.out.println("father : " + str);
26 }
27 }
28
29 class Son extends Father{
30 /**
31 * 参数String是CharSequence的子类,范围缩小
32 */
33 public void reduction(String str) {
34 System.out.println("son : " + str);
35 }
36 /**
37 * 范围扩大
38 */
39 public void enlarge(CharSequence str){
40 System.out.println("son : " + str);
41 }
42 }
3
4 public class LSP {
5
6 public static void main(String[] args) {
7 Father f = new Son();
8 Son s = new Son();
9 f.reduction("reduction");
10 s.reduction("reduction");
11
12 f.enlarge("enlarge");
13 s.enlarge("enlarge");
14 }
15
16 }
17
18 class Father{
19
20 public void reduction(CharSequence seq){
21 System.out.println("father : " + seq);
22 }
23
24 public void enlarge(String str){
25 System.out.println("father : " + str);
26 }
27 }
28
29 class Son extends Father{
30 /**
31 * 参数String是CharSequence的子类,范围缩小
32 */
33 public void reduction(String str) {
34 System.out.println("son : " + str);
35 }
36 /**
37 * 范围扩大
38 */
39 public void enlarge(CharSequence str){
40 System.out.println("son : " + str);
41 }
42 }
输出:
father : reduction
son : reduction
father : enlarge
father : enlarge
子类中的enlarge方法永远不会被执行到,以为传入参数类型被扩大了。 再看reduction()方法,子类的参数类String类型的,父类中的类型是CharSequence类型的,输入类型缩小,这时输出结果不同,看上面输出结果的前两个。这说明当把父类对象换为子类的对象时,行为不同了,这个违背了LSP的定义。
4.覆写或实现父类的方法时输出结果可以被缩小
实践:
.............