里氏替换原则(LSP)
程序员文章站
2024-01-14 14:21:58
...
里氏替换原则,用最简单的话描述就是:
凡是父类出现的地方,都可以会使用子类替换。而且替换为子类也不会产和那个任何错误或异常。
使用者根本就不需要知道是父类还是子类,但是反过来就不行了,有子类出现的地方,父类不一定适合。
里氏替换原则可以理解为四层含义:
1.子类必须完全实现父类的方法
注意:
a.在类中调用其他类时务必使用父类或者接口,如果不能使用父类或者接口,说明类的设计已经违背了LSP原则。
b.如果子类不能完整的实现父类的方法,或者父类的某些方法在子类中已经发生了畸变,那么建议断开父子继承关系,采用依赖、聚合、组合的关系代替
2. 子类可以有自己的个性
注意:
a.子类除了父类共有的部分外,当然可以有自己的行为和属性。所以,子类有了自己的个性化后,子类出现的地方,父类不一定适合出现,也就是向下转型(downcast)是不安全的
3. 覆盖或实现父类的方法时输入参数可以被放大
注意:
a.子类复写或重载父类方法时,参数类型要大于等于父类的方法的参数类型
b.满足a的条件,不管是父类还是子类,调用父类中的方法时,都是调用的父类,保证父类出现的地方都可以用子类替换,并且一般父类中声明的方法都是公共的或者高度抽象的,这样保证业务的独立性。
c.如果子类覆盖或重载父类方法是,参数类型小于父类方法的参数类型,那么就会直接调用到子类的方法,则会造成业务的混乱,不同的子类调用同一个业务出现不同的处理逻辑。
4. 子类覆盖或者重载父类方法时,返回值类型可以被缩小
注意:
父类的方法的返回值类型是T,子类相同方法返回值是S,那么S小于等于T。
分两种情况:
a.覆写:子类的方法和父类的方法名称、参数都一样,返回值子类的可以是父类的返回值类型,也可以是父类返回值类型的子类
b.重载:按照历史替换原则,子类方法的参数类型要大于等于父类的参数类型,所以子类中的方法根本不会调用。