上次讲了流大设计原则的单一职责和 开闭原则,没看过的可以先去看一看面向对象的六大设计原则(一)
本期讲:三、里氏替换原则:Liskov Substitution Principle,简称LSP
定义:如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。
是不是没看懂?理论家就喜欢把简单的问题复杂化。我们来看看关于里氏替换的第二种定义:所有引用基类的地方必须能透明地使用其子类的对象。这种定义还是比较抽象,来来来,给大家来一段金庸的小说:射雕中的九阴真经大家应该都知道,九阴真经貌似是一个叫黄裳(父类)的人写的。九阴真经(父类实现好的方法)写好了,后人就可用于修炼。杨过(子类)和小龙女(子类)就继承了黄裳(父类),并学会了九阴真经(实现好了的方法)。并且杨过自创的黯然销魂掌(子类自己的方法),小龙女自创了伤心断肠剑(子类自己的方法)。他们两个都变成了武林高手。而欧阳锋也是学的九阴真经,却乱改了其中的方法,最后搞的走火入魔,最后成了Bug。小龙女和杨过深知里氏替换原则的重要性!
其实里氏替换原则通俗点讲就是:子类可以拓展父类的功能,但不能改变父类原有的功能。它包含以下4层含义:
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
-
子类中可以增加自己特有的方法。
-
当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
- 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
我来看我们常用的Adapter
//当我们使用ListView的时候 都会使用这样一行代码也绑定资源适配器
public void setAdapter(ListAdapter adapter)
//通常我们写的Adapter都会继承自BaseAdapter 而BaseAdapter则继承子ListAdapter 然后实现父类未实现的一下方法
@Override
public int getCount() {
return listDatas == null ? 0 : listDatas.size();
}
@Override
public Object getItem(int position) {
return listDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return convertView;
}
//
但是我们从来都不回去重写父类已经实现好了的方法 比如
<pre name="code" class="java"> public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
//
如果我们这里胡乱改了BaseAdapter里面的方法会怎么样呢? 比如把notifyDataSetChanged里面的代码重写,就会导致我们的ListView再也无法更新数据了。如果我们
再大胆一点修改BaseAdapter中的已经实现的方法,后果就更严重了,可能会导致我们所有的ListView都无法正常使用。
通过上面,我们可以看到如果没有特殊需求,我们一般不回去修改BaseAdaper中已经为我们实现好的方法,其实在这里我们就很好的遵循了里氏替换原则。
本文为慕课网作者原创,转载请标明【原文作者及本文链接地址】。侵权必究,谢谢合作!
热门评论
和上一篇比较,风格差别甚大,是同一个人写的么?
已收藏,对初学者大有裨益