不知道为什么基本每一个介绍里氏替换原则的文章都要先在开头介绍里氏替换法则的由来,可能这个人实在很屌吧,“里”是这位麻省理工的教授名字的第一个发音。
这个如此屌的教授给出的定义也如此厉害:
定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。
定义2:所有引用基类的地方必须能透明地使用其子类的对象。
看不懂吧,换个姿势看
通俗的定义:所有引用基类的地方必须能透明地使用其子类的对象。
更通俗的定义:子类可以扩展父类的功能,但不能改变父类原有的功能。
这里所说的改变父类原有功能主要是说不要去重写父类的功能,也尽量少重载父类的功能
我看有些博客都提及过这个,但很少给出例子,我在这给出相应的例子,希望能帮助理解。前两个没什么问题,主要是后面两个
里氏替换原则包含以下4层含义:
(1)子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。
(2)子类中可以增加自己特有的方法。
(3)当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
这里设Vine是Liquid的子类
class Father
{
void drink(Vine vine)
{
System.out.println("实现父类");
}
}
class Son
{
void drink(Liquid liquid)
{
System.out.println("实现子类");
}
}
(4)当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
这里设Chinese是Voice的子类
class Father
{
public Voice speak()
{
Voice voice=new Voice();
System.out.println("实现父类");
return voice;
}
}
class Son
{
public Chinese speak()
{
Chinese chinese=new Chinese();
System.out.println("实现子类");
return chinese;
}
}