3、正方形类
package liskovsubstitution; /** * 正方形 */ public class Square implements Quadrangle { /** * 正方形边长 */ private long sideLength; @Override public long getLength() { return this.sideLength; } @Override public long getWidth() { return this.sideLength; } public long getSideLength() { return sideLength; } public void setSideLength(long sideLength) { this.sideLength = sideLength; } }
三、里氏替换原则代码示例 ( 方法入参 | 正面示例 )
重载 ( 输入参数 宽松 ) : 子类的方法 重载 父类的方法 时 , 方法的前置条件 ( 输入参数 ) , 要比 父类方法的输入参数更宽松 ;
如 : 父类的参数是 HashMap , 如果要符合 里氏替换原则 , 子类如果重载父类方法 , 那么需要使用 Map 类型参数 ;
( 这里注意区分 重写 与 重载 , 重写是重写父类方法 , 重载是函数名相同 , 参数不同 )
如果在父类中参数类型是 Map , 在子类中重载参数类型是 HashMap , 这样就会出现混乱的问题 ;
客户端调用时 , 可能不清楚情况 , 加入传入了 HashMap 参数 , 此时就有可能出现混乱 , 无法调用到 父类/子类的 正常重写方法 , 方法调用被重载方法拦截的情况 ;
如果 重载的方法 的参数 比父类的方法参数更严格 , 那么这就不是重载方法 , 而是重写方法 ;
1、父类
package liskovsubstitution; import java.util.HashMap; public class Father { public void method(HashMap map) { System.out.println("执行父类 void method(HashMap map) 方法"); } }
2、子类
package liskovsubstitution; import java.util.HashMap; import java.util.Map; public class Child extends Father { /** * 子类重写父类的方法 * 重写 ( 返回值 严格 ) : 当 子类的方法 重写 / 重载 / 实现 父类的方法时 * 方法的 后置条件 ( 返回值 ) 要 比父类更严格或相等 ; * @param map */ @Override public void method(HashMap map) { System.out.println("执行子类重写的 void method(HashMap map) 方法"); } /** * 重载的方法 * 重载 ( 输入参数 宽松 ) : 子类的方法 重载 父类的方法 时 * 方法的前置条件 ( 输入参数 ) , 要比 父类方法的输入参数更宽松 ; * * 如果在父类中参数类型是 Map * 在子类中重载参数类型是 HashMap * 这样就会出现混乱的问题 * 客户端调用时 , 可能不清楚情况 , 加入传入了 HashMap 参数 * 此时就有可能出现混乱 , 无法调用到 父类/子类的 正常重写方法 * 方法调用被重载方法拦截的情况 * * 如果 重载的方法 的参数 比父类的方法参数更严格 * 那么这就不是重载方法 , 而是重写方法 * * 遵守里氏替换原则很有必要 * @param map */ public void method(Map map) { System.out.println("执行子类重载的 void method(Map map) 方法"); } }
3、测试类
package liskovsubstitution; import java.util.HashMap; public class Main { public static void main(String[] args) { Child child = new Child(); HashMap hashMap = new HashMap(); // 此时传入的 HashMap 参数 // 由于重载的方法接收的参数是 Map 类型的 // 此时调用的是父类的方法 或 子类重写的 void method(HashMap map) 方法 // 不会调用重载的 void method(Map map) 方法 child.method(hashMap); } }
执行结果 :
执行子类重写的 void method(HashMap map) 方法
1
四、里氏替换原则代码示例 ( 方法入参 | 反面示例 )
在该反面示例中 , 父类中的方法参数是 Map 类型 , 子类中重载的方法参数是 HashMap 类型 ;
如果客户端调用该方法 , 传入一个 HashMap 类型的参数 , 就会出现只能调用重载方法 , 无法调用父类中定义的方法或子类中重写的方法 ;
重载的方法比父类方法参数严格 , 就会出现上述情况 ;
1、父类
package liskovsubstitution; import java.util.Map; public class Father { public void method(Map map) { System.out.println("执行父类 void method(HashMap map) 方法"); } }
2、子类
package liskovsubstitution; import java.util.HashMap; import java.util.Map; public class Child extends Father { /** * 子类重写父类的方法 * 重写 ( 返回值 严格 ) : 当 子类的方法 重写 / 重载 / 实现 父类的方法时 * 方法的 后置条件 ( 返回值 ) 要 比父类更严格或相等 ; * @param map */ @Override public void method(Map map) { System.out.println("执行子类重写的 void method(HashMap map) 方法"); } /** * 重载的方法 * 重载 ( 输入参数 宽松 ) : 子类的方法 重载 父类的方法 时 * 方法的前置条件 ( 输入参数 ) , 要比 父类方法的输入参数更宽松 ; * * 如果在父类中参数类型是 Map * 在子类中重载参数类型是 HashMap * 这样就会出现混乱的问题 * 客户端调用时 , 可能不清楚情况 , 加入传入了 HashMap 参数 * 此时就有可能出现混乱 , 无法调用到 父类/子类的 正常重写方法 * 方法调用被重载方法拦截的情况 * * 如果 重载的方法 的参数 比父类的方法参数更严格 * 那么这就不是重载方法 , 而是重写方法 * * 遵守里氏替换原则很有必要 * @param map */ public void method(HashMap map) { System.out.println("执行子类重载的 void method(Map map) 方法"); } }