里氏代换原则(Liskov Substition Principle)
里氏代换原则(LSP)的准确描述:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得T1定义的所有程序p在所有对象o1都代换成o2的时候,程序p的行为没有变化,那么类型T2是类型T1的子类型。
对于里氏代换原则来说反过来是不成立的。
Java对里氏代换原则的支持
这里会有一个很经典的JAVA乃至是所有面向对象语言的一个经典问题。如果在父类中有一个public的方法。问是否可以在子类型中overload成private?利用里氏代换原则我们就可以很清楚的理解这个问题。假设这个命题是成立的,那么我们根据里氏代换原则将出现的父类型public方法替换成子类型的private方法。那么这里会出现一个问题。由于子类型的相应方法是private的,他将不能被客户端调用。到这里这个命题就出现了矛盾。所以在父类中有一个public的方法。问是不可以在子类型中overload成private。
对于这一点JAVA编译器会对其经行检查,在编译的时候就不会让这种类型的程序通过。
Java对里氏代换原则的局限
Java对里氏代换原则的局限体现在JAVA编译器只对LSP的精度经行检查,不能检查一个系统在现实和商业逻辑上的满足。
里氏代换原则与几种模式:
策略模式(Strategy):如果有一组算法,那么将每一个算法封装起来,使他们可以互换。
封装的概念不难理解,使所有的算法可以互换则需要将所有的具体策略角色放到一个类型等级结构中,使他们有共同的接口。这就是LSP在策略模式中的真实体现。
合成模式(Composite):通过树结构描述整体与部分的关系。从而将单纯元素与复合元素同等看待。由于单纯元素和复合元素都是抽象元素的子类。因此,两者都可以替换抽象元素出现在的任何地方。
代理模式(Proxy):代理模式给某一个对象提供一个代理对象,并有代理对象控制对原对象的引用,代理对象模式能成立的关键,就在于代理模式与真实主题模式都是抽象主题角色的子类,客户端只知道抽象主题,而代理主题可以替换抽象主题出现在任何需要的地方,而真实主题隐藏在幕后