接口与类
一个具体类对具体父类的继承和对接口的继承是有区别的。
对接口的继承 | 具体父类的继承 |
具体类要实现接口的全部功能 | 具体子类可以选择性重写具体父类的部分需要的功能 |
具体类都可以增加新功能 |
overload与override
override | overload | |
函数名 | 与父类一致 | 与父类一致 |
参数 | 与父类一致 | 与父类不一致 |
返回值 | 不做要求 | 不做要求 |
LSP替换原则
内容:
(1)子类型可以增加方法,但是不可以删除基类的方法·子类型需要实现抽象类型中的所有未实现方法
(2)当子类覆盖或实现父类的方法时,方法的返回值要比父类更严格。(子类型中重写的方法必须有相同或子类型的返回值或者符合 co-variance 的参数)
(3)当子类覆盖或实现父类的方法时,方法的形参要比父类方法的更为宽松。(子类型中重写的方法必须使用同样类型的参数或者符合 contra-variance 的参数)。
子类型中重写的方法不能抛出额外的异常
简单记为∶
●更强的不变量
● 更弱的前置条件
●更强的后置条件
LSP中的协变:
父类→子类∶越来越具体
返回值类型∶不变或更具体
异常的类型∶不变或更具体
LSP中的逆变:
父类→子类∶越来越具体
参数类型∶不变或越来越抽象
在Java中LSP与override和overload的关系:
在Java中,协变由override负责,此时:
函数名与父类一致
参数与父类一致
返回值与父类一致或者比父类更为具体
class T{
Object a(int b){}
}
class S extends T{
@Override
String a (int b){}
}
逆变由overload负责,此时:
函数名与父类一致
参数比父类更为抽象
返回值与父类一致
class T{
void c(String s){}
}
class S extends T{
@Override
void c(Object s){}
}