C#教您一步步摆脱面向过程:里氏替换

前面有几篇文章,已经教了一些方式或者方法,帮助您摆脱娘胎自带的面向过程编程,从而转为面向对象。

如果您有一路仔细看的话,相信我,您应该可以掌握的,后面还会再举一些面向对象的代码实操例子,一步一步演练如何编写出面向对象的代码。我会尽量多举几个例子,多写几篇实战演练,以便您掌握面向对象,现在先继续学面向对象的基础知识。


本文讲解面向对象的原则之一:里氏替换。

一、原则起源

里氏替换原则的内容可以描述为: “派生类(子类)对象可以在程式中代替其基类(超类)对象。” 以上内容并非利斯科夫的原文,而是译自罗伯特·马丁(Robert Martin)对原文的解读。

芭芭拉·利斯科夫与周以真(Jeannette Wing)在1994年发表论文并提出以上的Liskov代换原则

以上内容来自于众里寻他千百$度。

二、谁替换谁,哪里替换?

谁替换谁?子类可以替换掉父类。

哪里替换?任何凡是父类可以出现的地方,子类都可以换掉它,然后出现在那里。

 

上图是一个家庭成员类和烹饪类,主要目的是为了炒菜。

那么哪里可以被里氏替换呢?下图红圈部分,凡是父类出现的位置,都可以被子类换掉。

 

如上图,红圈“家庭成员”,我们用它的子类“小明”、“小红”、“小华”等替换掉它,这是里氏替换。

三、好好的,我为什么要换?

问的好,我干嘛要换它。

之前我们有一个项目叫烹饪,对,没错,有一个家庭成员是会主厨的,他就是小明。似乎对于烹饪来说,一切都是没有问题的。嗯,也确实没有问题。

好的,下面作为家主,我要宣布,明天我们要去娱乐了,有唱歌有跳舞,还要有个主持人。嗯,主持人,咱们家只有“小红”有主持天份,非她莫属。于是之前设计的类,矛盾和问题就出现了,下面请看:

 

我如果给“家庭成员”这个父类,增加一个方法“会主持”,那就问题大了,因为咱们家只有小红会主持,小明呢压根就不会的。这么定义的话,有什么问题吗?当然有问题啦,问题还大了:

 

如上图红圈,因为烹饪的时候,new的对象小明,小明去炒菜的,结果发现下图:

 

小明不仅会炒菜,还会主持了,我们都知道小明压根不会主持,你现在却让他拥有了“主持”功能。这与业务是矛盾的。

四、那么怎么办呢?

我们应该给子类“小红”,创建“会主持”的方法,而不是写到“家庭成员”这个父类中。如下图:

 

这样的话,就只有小红会主持了。

 

然后这里的小红,由于是子类,所以,它不可以再被里氏替换。这说明子类,具有更严格的定义。

五、里氏替换具有下面的特征

  • 子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法。
  • 子类中可以增加自己特有的方法。
  • 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

六、实践运用

依赖的时候,尽量使用依赖倒转,这样的话,你就可以在任何地方使用它们的子类来替换它们了。

这话我也不知道读者能不能看得明白。

 

比如上面的事件委托,您可以在任何地方,使用EventArgs的子类,来作为参数传进去。而不一定非得是EventArgs这个父类的实例。

 

好的,祝您用餐愉快。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值