子类中尽量不要重写父类的方法 在适当的情况下,可以通过聚合,组合,依赖 来解决问题
使用前
需求:完成两个数的减法运算,封装成计算器;计算器的种类有很多种( 算术型计算器 、科学型计算器、程序计算器....)
先简单的来实现算数型计算器的减法运算功能;
package com.javaxl.design.rules.richterReplacement.before;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 15:15
* 所有计算器的父类
*/
public abstract class Cal {
protected abstract double minus(double x, double y);
}
//最基础的算数型的计算器
class BaseCountCal extends Cal{
@Override
protected double minus(double x, double y) {
return x - y;
}
}
public class Client {
public static void main(String[] args) {
Cal cal = new BaseCountCal();
// 完成6与3的减法
System.out.println(cal.minus(6, 3));
}
}
需求变更,需要做一个程序计算器,完成两个数的减法
package com.javaxl.design.rules.richterReplacement.beforePlus;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 15:15
* 所有计算器的父类
*/
public abstract class Cal {
protected abstract double minus(double x, double y);
}
//最基础的算数型的计算器
class BaseCountCal extends Cal {
@Override
protected double minus(double x, double y) {
return x - y;
}
}
/**
* byte i=-128;
* System.out.println((byte)(i-1)); 127
* 完成程序计算器的减法
*/
class ProcessCal extends Cal{
@Override
protected double minus(double x, double y) {
return x+y;
}
}
public class Client {
public static void main(String[] args) {
Cal cal = new BaseCountCal();
// 完成6与3的减法(基本算数计算器)
System.out.println(cal.minus(6, 3));
// 完成6与3的减法(程序计算器)
cal = new ProcessCal();
System.out.println(cal.minus(6, 3));
}
}
使用后
先简单的来实现算数型计算器的减法运算功能;
这里的代码省略,与上面需求变更前的代码保持一致...
需求变更,需要做一个程序计算器,完成两个数的减法
package com.javaxl.design.rules.richterReplacement.afterPlus;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-16 15:15
* 所有计算器的父类
*/
public abstract class Cal {
protected abstract double minus(double x, double y);
protected abstract double mul(double x, double y);
}
//最基础的算数型的计算器
class BaseCountCal extends Cal {
@Override
protected double minus(double x, double y) {
return x - y;
}
protected double mul(double x, double y) {
return x * y ;
}
}
class ProcessCal{
// 聚合Cal抽象类,不变的引用它,变化的不引用
private Cal cal;
public ProcessCal(Cal cal) {
this.cal = cal;
}
protected double minus(double x, double y) {
return x + y ;
}
protected double mul(double x, double y) {
return cal.mul(x,y) ;
}
}
public class Client {
public static void main(String[] args) {
Cal cal = new BaseCountCal();
// 完成6与3的减法(基本算数计算器)
System.out.println(cal.minus(6, 3));
// 完成6与3的减法(程序计算器)
ProcessCal processCal = new ProcessCal(cal);
System.out.println(processCal.minus(6, 3));
// 完成6与3的乘法(基本算数计算器)
System.out.println(cal.mul(6, 3));
// 完成6与3的减法(程序计算器)
System.out.println(processCal.mul(6, 3));
}
}
从上面可以看出
不遵循里氏替换原则:Cal定义的两个数的减法,直接被子类ProcessCal给覆写了,覆写的结果导致调用方Client使用的时候未能得到自己想要结果;原因在于该程序类与类之间的耦合性高(继承关系)
遵循里氏替换原则:Cal定义的两个数的减法,ProcessCal类的多数行为(加乘除)与Cal类一致,此时应该使用聚合/组合的方式,这样的话解耦了ProcessCal与Cal之间的关系,调用方Client使用减法运算的时候会更加关注ProcessCal减法的实现过程;
这也就是里氏替换所说的,建议使用聚合/组合的方式来解决依赖关系,子类尽量不要覆写父类的方法;
over......
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有