面向对象的原则里氏替换原则

2016-03-17  本文已影响228人  刘涤生

里氏替换原则

里氏替换原则的英文全称是Liskov Substitution Principle,缩写是LSP。

LSP第一种定义是:如果对每一个类型的为S的对象O1,都有类型为T的对象O2,使得以T定义的所有程序P在所有对象O1都替换成O2时,程序P的行为不会发生变化,那么类型S是类型T的子类型。这不太好理解。

LSP的第二种定义是:所有引用基类的地方必须能透明地使用其子类的对象。通俗的讲就是:只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或者异常,使用者可能根本就不需要知道是父类还是子类,但是,反过来就不行了,有子类出现的地方,父类未必就能适应。因为子类有的东西父类不一定有。

说了这么多,最终总结就两个字:抽象。为了便于理解这个原则,我们写了一个简单示例来描述,先看UML图:

里氏替换原则.png

再来看看具体的代码:

/**
 * 窗口类
 */
public class Window  {

    public show(View chile) {
        chile.draw();
    }
}

/**
 * 建立视图抽象,测量视图的宽高为公用代码,绘制实现交给具体的子类
 */
public abstract class View {
    public abstract void draw();
    public void measure(int width,int height) {
    }
}

/**
 * Button的具体实现
 */
public class Button extends View {

    @Override
    public void draw() {
        //绘制Button
    }
}

/**
 * TextView的具体实现
 */
public class TextView extends View {

    @Override
    public void draw() {
        //绘制TextV
    }
}

上述示例中,Window依赖于View,而View定义了一个视图抽象,measure是各个子类共享的方法,子类通过覆写View的draw方法实现各自的功能。任何继承自View的子类都可以设置给Window的show方法,这就是里氏替换原则。通过里氏替换,就可以自定义各自各样的view,然后传递个Window,Window负责组织view,并且将View显示到屏幕上。

里氏替换原则的核心是抽象,抽象又依赖于继承这个特性,在OOP当中,继承的优缺点都相当的明显。优点为:

继承的缺点:

结束

开闭原则中的示例图片缓存系统也很好地反应了里氏替换原则,即MemoryCache、DiskCache、DoubleCache都可以替换成ImageCache的工作,并保证行为的正确性。实际中,开闭原则和里氏替换原则往往是相互关联的,通过里氏替换来达到扩展开放、修改关闭的效果。然而,这两个原则都强调一个OOP的重要特性--抽象。

参考书籍

《Android源码设计模式》 何红辉、关爱民著

上一篇下一篇

猜你喜欢

热点阅读