1 代码演练
1.1 继承关系判别(是否是真正意义的继承)
1.2 入参控制
1.3 出参控制
1 代码演练
1.1 继承关系判别(是否是真正意义的继承)(其实我觉得这个例子有点牵强)
1.1.1 反例
结论:
确定继承关系的时候一定要判断好,是否父类的方法子类可以继承。传统意义的正方形是矩形的子类,在这里是不适用的。
测试类1:
package com.geely.design.principle.liskovSubstitutation; public class TestSquare { public static void resize(Rectangle rectangle){ while(rectangle.getWidth()<=rectangle.getLength()){ rectangle.setWidth(rectangle.getWidth()+1); System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth()); } } public static void main(String [] args){ Rectangle rectangle = new Rectangle(); rectangle.setWidth(10); rectangle.setLength(20); resize(rectangle); } // public static void main(String [] args){ // Square square = new Square(); // square.setLength(10); // resize(square); // } }
打印结果1:
"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=17363:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.TestSquare 长为20****************宽为11 长为20****************宽为12 长为20****************宽为13 长为20****************宽为14 长为20****************宽为15 长为20****************宽为16 长为20****************宽为17 长为20****************宽为18 长为20****************宽为19 长为20****************宽为20 长为20****************宽为21 Process finished with exit code 0
测试类2:
package com.geely.design.principle.liskovSubstitutation; public class TestSquare { public static void resize(Rectangle rectangle){ while(rectangle.getWidth()<=rectangle.getLength()){ rectangle.setWidth(rectangle.getWidth()+1); System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth()); } } // public static void main(String [] args){ // Rectangle rectangle = new Rectangle(); // rectangle.setWidth(10); // rectangle.setLength(20); // resize(rectangle); // } public static void main(String [] args){ Square square = new Square(); square.setLength(10); resize(square); } }
打印结果2:
************************************** 长为241350****************宽为241350 长为241351****************宽为241351 长为241352****************宽为241352 长为241353****************宽为241353 长为241354****************宽为241354 **************************************
矩形类:
package com.geely.design.principle.liskovSubstitutation; public class Rectangle { private long length; private long width; public long getLength() { return length; } public void setLength(long length) { this.length = length; } public long getWidth() { return width; } public void setWidth(long width) { this.width = width; } }
正方形类:
package com.geely.design.principle.liskovSubstitutation; public class Square extends Rectangle { private long sideLength; public long getSideLength() { return sideLength; } public void setSideLength(long sideLength) { this.sideLength = sideLength; } @Override public long getLength() { return getSideLength(); } @Override public void setLength(long length) { setSideLength(length); } @Override public long getWidth() { return getSideLength(); } @Override public void setWidth(long width) { setSideLength(width); } }
1.1.2 正方形矩形实现四边形
结论:
子类行为规则应与父类行为规则一致,如果子类达不到这一点,则会违背里氏替换原则,违背里氏替换原则会怎样?继承逻辑混乱,代码不便于维护
测试类:
package com.geely.design.principle.liskovSubstitutation; public class TestSquare2 { public static void resize(Rectangle rectangle){ while(rectangle.getWidth()<=rectangle.getLength()){ rectangle.setWidth(rectangle.getWidth()+1); System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth()); } } // public static void main(String [] args){ // Rectangle rectangle = new Rectangle(); // rectangle.setWidth(10); // rectangle.setLength(20); // resize(rectangle); // } public static void main(String [] args){ Square square = new Square(); square.setSideLength(10); resize(square); } }
四边形接口:
package com.geely.design.principle.liskovSubstitutation; public interface Quadrangle { long getWidth(); long getLength(); }
矩形类:
package com.geely.design.principle.liskovSubstitutation; public class Rectangle implements Quadrangle{ private long length; private long width; public void setLength(long length) { this.length = length; } public void setWidth(long width) { this.width = width; } @Override public long getWidth() { return width; } @Override public long getLength() { return length; } }
正方形类:
package com.geely.design.principle.liskovSubstitutation; public class Square implements Quadrangle{ private long sideLength; public long getSideLength() { return sideLength; } public void setSideLength(long sideLength) { this.sideLength = sideLength; } @Override public long getWidth() { return sideLength; } @Override public long getLength() { return sideLength; } }
1.2 入参控制
1.2.1 里氏替换原则正例
结论:
重载的时候入参更加宽松,可以不引起逻辑的混乱。
测试类:
package com.geely.design.principle.liskovSubstitutation.inputmethod; import java.util.HashMap; public class TestChild { public static void main(String [] args){ Child child = new Child(); HashMap hashMap = new HashMap(); child.method(hashMap); } }
子类:
import java.util.HashMap; import java.util.Map; public class Child extends Base{ // @Override // public void method(HashMap hashMap) { // System.out.println("执行子类的HashMap方法"); // } /** * 子类重载 * 重载的时候入参 Map比 Hashmap宽松,此时执行的时候会执行父类,不执行重载的类 * @param hashMap */ public void method(Map Map) { System.out.println("执行子类Map方法"); } }
父类:
package com.geely.design.principle.liskovSubstitutation.inputmethod; import java.util.HashMap; public class Base { public void method(HashMap hashMap){ System.out.println("执行父类HashMap方法"); } }
打印结果:
"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=21089:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.inputmethod.TestChild
执行父类HashMap方法
Process finished with exit code 0
1.2.2 里氏替换原则反例
测试类:
package com.geely.design.principle.liskovSubstitutation.inputmethod; import java.util.HashMap; public class TestChild { public static void main(String [] args){ Child child = new Child(); HashMap hashMap = new HashMap(); child.method(hashMap); } }
子类:
package com.geely.design.principle.liskovSubstitutation.inputmethod; import java.util.HashMap; import java.util.Map; public class Child extends Base{ // @Override // public void method(Map map) { // super.method(map); // } public void method(HashMap hashMap) { System.out.println("执行子类HashMap方法"); } }
父类:
package com.geely.design.principle.liskovSubstitutation.inputmethod; import java.util.HashMap; import java.util.Map; public class Base { public void method(Map map){ System.out.println("执行父类HashMap方法"); } }
打印日志:
"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=21674:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.inputmethod.TestChild
执行子类HashMap方法
Process finished with exit code 0
1.3 出参控制
1.3.1 反例
结论:
子类的出参如果包含父类,会直接报错。
子类:
package com.geely.design.principle.liskovSubstitutation.outputmethod; import java.util.Map; public class Child extends Base { @Override public Object method() { return null; } }
父类:
package com.geely.design.principle.liskovSubstitutation.outputmethod; import java.util.Map; public abstract class Base { public abstract Map method(); }