里氏替换
用一个子类来代替基类,程序的行为不变,那么就符合里氏替换。
最常见的违反里氏替换原则的例子:子类存在空的虚函数即一个子类对于基类的某些方法进行屏蔽将其改成空函数。也成为子类的退化。
里氏替换的意义在于更好的实现OCP。
如果我们的子类不能完全的代替基类,那么基类的抽象就是有问题的,必然会导致,在拓展子类功能的时候需要修改基类。
判断是否符合里氏替换的方法是判断两个类是否存在IS-A的关系,即子类是一个基类吗?比如说,鸭子是鸟吗?
但符合IS-A的关系的对象不一定符合里氏替换。还要看对象的特性,即可能产生变化的和地方。
比如说正方形是一个长方形,这个事没有问题的。
1 class Rectangle 2 { 3 void Width(int w); 4 void Height(int h); 5 } 6 7 class Suqare : Rectangle 8 { 9 10 }
正方形是从长方形中继承出来的,但是正方形的长和宽是一样的,而长方形不是,那么我对正方形单独设置长和宽的时候,就会和长方形单独设置长和宽的时候的行为不一致,这就违反了历史替换原则。从这种角度来说正方形和长方形是不应该存在继承关系的。
比较好的方式是抽取一个公共类的。
class Shape { 公共功能部分 } class Rectangle:Shape { void Width(int w); void Height(int h); } class Suqare:Shape { void length(int l); }