05. 里氏代换原则
标准定义
若对每个类S的对象O1,都存在一个类T的对象O2,使得在所有针对T编写的程序P中,用O1替换O2后,程序P行为功能不变,则S是T的子类
生活案例
俗话说得好,“龙生龙,凤生凤,老鼠的儿子会打洞”,在实际的生活当中,确实挺常见的事情。有其父必有其子,父亲做得到的,儿子也做得到,而且儿子还能做得更好。”对钱不感兴趣”的马云,父亲马来法,长期担任浙江省曲艺家协会领导,有着很广的政商关系。“只不过房子大了点”的马化腾,父亲马陈术曾担任交通部海南八所港务局会计、统计员、计划科科长、副局长,深圳市航运总公司计财部经理、总经理,深圳市盐田港建设指挥部副总指挥,深圳市盐田港集团有限公司副总经理,1997年被选为盐田港上市公司的董事。大三的时候就辍学比尔盖茨,父亲是著名律师,母亲是社会活动家,是华盛顿大学的董事国际联合劝募的主席。
不可否认,良好的教育背景,能够促进一个人的成长,帮助一个家庭迈上新的台阶。当然,起跑线落后的孩子也不能灰心,努力追求,也能达到一个不错的水平。里氏代换原则就是说明这样的一件事情,父亲能做到的,儿子也能做到,而且儿子可以做得更好,但是儿子能做到的,父亲不能做到。
程序例子
程序的业务还是举04. 开闭原则的业务,CanonHighPrinter现在又升级了,他不仅仅能够打印彩色和黑白的文档,他还能充当碎纸机使用,把一个文档给删掉。相关的代码实现如下:
public class CanonHighPrinter extends CanonSimplePrinter{
public void delete() {
System.out.println("删除文档");
}
}
注意,在父类CanonSimplePrinter是没有delete方法的,也就是说他没有删除文档的功能,根据里氏代换原则,CanonHighPrinter可以调用父亲的print方法和自己的delete方法,而在CanonSimplePrinter中,只能调用自己的print方法,对于儿子CanonHighPrinter的delete方法是不能调用的。
调用程序如下:
public class Main() {
public static void main(String[] args) {
IPrinter highPrinter = new CanonHighPrinter();
highPrinter.print();
((CanonHighPrinter) highPrinter).delete();
IPrinter simplePrinter = new CanonSimplePrinter();
simplePrinter.print();
// error 出现 java.lang.ClassCastException
((CanonHighPrinter) simplePrinter).delete();
}
}
当父亲simplePrinter试图转换成儿子CanonHighPrinter来调用delete()方法,显示是失败的,发生java.lang.ClassCastException,父类的实现不能转换成子类的实现。