为什么版本1的类继承层级违反了里氏替换原则(LSP)?
版本1不符合里氏替换原则(LSP)的原因
里氏替换原则的核心要求是:子类可以替换父类出现的所有位置,且替换后程序的原有逻辑正确性不会被破坏,子类必须完全遵守父类定义的方法行为契约。
版本1的设计问题
- 版本1中父类
SumCalculator的Calculate()方法有明确的行为约定:返回传入数组中所有数字的总和,这是所有调用SumCalculator的代码都会默认遵循的预期。 - 子类
EvenNumbersSumCalculator重写Calculate()后,行为变成了仅返回数组中偶数的和,完全违背了父类定义的方法契约。 - 实际场景中会直接破坏业务逻辑:比如现有一段业务逻辑接收
SumCalculator类型参数,用来计算员工当月工资总和,你把EvenNumbersSumCalculator的实例传进去,得到的总金额会直接少掉所有工资金额为奇数的员工薪资,业务逻辑完全出错,这就说明子类无法安全替换父类,不符合LSP要求。
版本2的优化逻辑
- 版本2抽取了抽象父类
Calculator,它的抽象Calculate()方法只做了最基础的约定:基于传入的整数数组返回一个整数计算结果,没有约定具体的计算规则。 SumCalculator和EvenNumbersSumCalculator都直接继承Calculator,各自的Calculate()实现都符合抽象父类的契约,不存在行为违背的问题。- 此时所有依赖
Calculator的代码,天然知道具体计算逻辑由子类实现,替换任意子类都不会打破调用方的原有预期,完全符合LSP要求。
内容的提问来源于stack exchange,提问作者user16276760
相关产品推荐
相关产品推荐

