1 定义
子类型(subtype)必须能够替换掉他们的基类型(base type)。
详细来说,可以看作是以下五条:
1、子类型可以添加方法,但是不可以删除基类的方法
2、子类型需要实现抽象类型中所有未实现的方法
3、当子类覆盖或者实现父类的方法时,方法的返回值要比父类更加严格。(子类型中的重写的方法必须有相同或子类型的返回值或者返回协变的参数)
4、当子类覆盖或者实现父类的方法时,方法的参数要比父类更加宽松。(子类型中的重写的方法必须使用同样类型的参数或者符合逆变的参数)
5、子类型中重写的方法不能抛出额外的异常
这里解释一下协变和逆变:
协变(co-variance)返回值类型不变或者更加具体,异常不变或者更加具体
逆变(contra-variance)参数类型:不变或更加抽象
(应当指出,java并不支持逆变,如果要使用逆变应当使用重载的方法)
个人理解:协变和逆变都是做了一件事,即使得规约更加具体。
2 例子
某年考了这样一题
先给出答案B
首先A把public变成了private,这会影响客户端使用,违反了子类型应该能替换父类的前提。
B中都满足LSP,同时是能通过java静态检查的
C抛出了更具体地异常,违反LSP
D、D其实是满足LSP原则的但是注意java不支持逆变,会将它视作overload而非override
某年考了这样的一道题,D选项就用到了LSP的知识,首先给出答案是B,因为Override仅仅是一个声称,不会影响代码。
A、C、D都错
A中interface一般不加默认为public。C中JAVA是支持一个类实现多个接口的。
再看D:首先要回顾在泛型中的知识,即List



