一直都搞不明白里氏替换原则的后面两条,到今天才知道原来是自己没有认真思考。闲话不说,记录下来吧以后方便查看。
里氏替换原则的主要作用就是规范继承时子类的一些书写规则。其主要目的就是保持父类方法不被覆盖,试想一下,如果你想覆盖父类的方法,干嘛还要继承他,直接重新写一个类不就完了。
里氏替换原则包含以下4层含义:
- 子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。
- 子类中可以增加自己特有的方法。
- 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
- 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
始终记住里氏替换原则的最终目的就可以,就是保持父类的方法不被覆盖。所以前面两层含义和最后一条很容易理解,重点记下我觉得比较难以理解的第三条。
第三条:当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
父类一个方法func(HashMap map);子类方法func(Map map);
父类实例f,子类实例s,为了遵守保持所有引用基类的地方必须能透明地使用其子类的对象这一原则,f.func(HashMap或子类) 必须和s.func(HashMap或子类) 调用的是同一方法,试想如果子类方法func参数范围比父类的窄的话,s.func就会优先调用子类的方法,这样就违背了里氏替换原则的基本定义了。