加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

6大设计原则之里氏替换原则

发布时间:2020-12-14 05:23:37 所属栏目:百科 来源:网络整理
导读:首先说说继承: ????继承的优点: ????????1.代码共享 ????????2.提高代码的重用性 ????????3.子类可以形似父类但又异于父类 ????????4.提高代码的可重用性 ????????5.提高代码的开放性 ????缺点:1.继承是带有侵入性的 ????????? 2.降低了代码的灵活性 ????

首先说说继承:

????继承的优点:

????????1.代码共享

????????2.提高代码的重用性

????????3.子类可以形似父类但又异于父类

????????4.提高代码的可重用性

????????5.提高代码的开放性

????缺点:1.继承是带有侵入性的

????????? 2.降低了代码的灵活性

????????? 3.增强了耦合

什么是里氏替换?

????简单说就是将父类出现的地方替换成子类,系统不会出现新的错误或异常。是实现抽象化的一种规范。


  1. 尽量不要重写父类已实现的方法

  2. 尽量不要重载父类的方法;当子类重载父类方法时,方法的入参要比父类的入参更加宽松

  3. 所有派生类的行为功能必须和使用基类的期望保持一致,避免出现派生类与基类不一致的行为

  4. 子类完全实现父类的方法,当子类实现父类的抽象方法时,返回值要比父类的返回值更加严格



有名的两个悖论:正方形不是长方形和企鹅不是鸟;



这里简单说说企鹅不是鸟:

生物学中鸟是脊椎动物的一类,温血卵生,用肺呼吸,几乎全身有羽毛,后肢能行走,前肢变为翅,大多数能飞。鸟的主要特征是:身体呈流线型(纺锤型或梭形),大多数飞翔生活。体表被覆羽毛,一般前肢变成翼(有的种类翼退化);胸肌发达;直肠短,食量大消化快,即消化系统发达,有助于减轻体重,利于飞行;心脏有两心房和两心室,心搏次数快。体温恒定。呼吸器官除具肺外,还有由肺壁凸出而形成的气囊,用来帮助肺进行双重呼吸。

但这里我们来设计一个与鸟相关的程序:

所有的鸟都由鸟类派生:

鸟类:

??public?class?Bird
????{
????????//速度
????????private?float?velocity;

????????public?virtual?void?Fly()
????????{
????????????Console.WriteLine("I?Can?Fly?!!!");
????????}

????????public?virtual?void?SetVelocity(float?v)
????????{
????????????this.velocity?=?v;
????????}

????????public?double?GetVelocity()
????????{
????????????return?this.velocity;
????????}
????}
//企鹅
????public?class?Penguin:Bird
????{
????????public?override?void?Fly()
????????{
????????????Console.WriteLine("?I?Can't?Fly?...");
????????}

????????public?override?void?SetVelocity(float?v)
????????{
????????????//企鹅不会飞,所以速度为0
????????????base.SetVelocity(0);
????????}
????}
//测试类
????class?TestBird
????{
????????public?static?void?CalcTime(Bird?bird)
????????{
????????????float?length?=?10000;
????????????try
????????????{
????????????????Console.Write("通过10000长的距离,耗时:");
????????????????Console.WriteLine(length?/?bird.GetVelocity());
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????Console.WriteLine(ex.Message);
????????????}
????????}
????}


运行结果:

wKiom1OElXKg9KTVAABYXKCTUz4223.jpg

这里C#中虽然没有抛出异常,但从结果中我们看出再计算Penguin所用飞行时间时已经有了除0操作,这是不被允许的;已经和我们的期望相违背。

所以Penguin类和Bird类之间的继承关系违反了里氏代换原则,它们之间的继承关系不成立,企鹅不是鸟。


“企鹅到底是不是鸟”,企鹅是鸟也不是鸟,这个结论似乎就是个悖论。产生这种情况有两方面的原因:

  1. 没有搞清楚类的继承关系的定义

    我们经常说类的继承关系就是一种“Is-A”关系,实际上指的是行为上的“Is-A”关系,

    也就是说是关注的对象的行为,这里是使用行为来对对象进行分类的,只有行为一致才能抽象出一个类来

  2. 要看清程序依赖的具体环境

    具体需求和环境而定,(如果要求根据是否是卵生来区分是否是鸟类,那企鹅就很明显符合要求了)

里氏替换原则实际上是给了我们一个类的继承原则:

如果不符合里氏替换原则则说明子类不应该继承该父类,需要考虑重新设计他们之间的关系。

(采用依赖、聚集组合等关系替换)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读