前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式之里氏替换原则C++实现

设计模式之里氏替换原则C++实现

作者头像
用户9831583
发布2022-06-16 14:33:55
3920
发布2022-06-16 14:33:55
举报
文章被收录于专栏:码出名企路

里氏替换原则: 子类可以扩展父类的功能,但不能改变父类原有的功能,不要重写父类的方法。

原因:如果通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差。

实现思想:取消原来的继承关系,重新设计它们之间的关系。

具体示例:

燕子会飞,几维鸟不会飞,其速度为0,计算两者飞行速度。UML类图如下

第一步:添加 bird.h

代码语言:javascript
复制
#pragma once//这个是必须的,不然子类没法引用的
#include <iostream>
using namespace std;
class Bird
{
    public:
        void setspeed(double speed){bird_speed=speed;}
        double gettime(double dis){return (dis/bird_speed);}
    public:
        double bird_speed;
};

第二步:添加swallow.h

代码语言:javascript
复制
#include "bird.h"
class Swallow:public Bird
{
};

第三步:添加 brownkiwi.h

代码语言:javascript
复制
#include "bird.h"
class BrownKiwi: public Bird
{
    public:
        void setspeed(double speed){bird_speed=0;}
};

第四步:实现 main.cpp

代码语言:javascript
复制
#include "swallow.h"
#include "brownkiwi.h"
#include "bird.h"
#include <csignal>
#include <cmath>
#include "notbird_brownkiwi.h"
//异常处理
void output(double x,double y)
{
    if( isinf(x))
        throw x;
    if(isinf(y))
        throw y;
    if(!isinf(x) && !isinf(y))
    {
        cout<<"燕子飞行了:"<<x<<" 小时"<<endl;
        cout<<"几维鸟飞行了:"<<y<<" 小时"<<endl;
    }
}

int main()
{  
    //父类指针指向子类对象
    //这样定义不对
   // Bird *bird1=new Swallow();
  //  Bird *bird2=new BrownKiwi();
  
   //父类指针指向子类对象
   /* Swallow bird1_;
    BrownKiwi bird2_;
    Bird* bird1=&bird1_;
    Bird* bird2=&bird2_;
      //转化为父类对象
      Bird _bird2=*bird2;*/

   //定义子类对象
   Swallow* bird1=new Swallow();
  BrownKiwi* bird2=new BrownKiwi();//
 
    bird1->setspeed(120);
    bird2->setspeed(120);
    cout<<"飞行300公里"<<endl;
   //  _bird2.setspeed(120);
    double x=bird1->gettime(300);
    double y=bird2->gettime(300);
    try
    {
           output(x,y);
       //  cout<<"几维鸟飞行了:"<<_bird2.gettime(300)<<" 小时"<<endl;
    }
    catch (double)
    {
        std::cerr << "除数是0! 发生错误!" << std::endl;
    }
   return 0;
}

结果显示:

运行错误:几维鸟类重写了鸟类的 setspeed方法,违背了里氏替换原则。

正确做法:取消几维鸟原来的继承关系,定义鸟和几维鸟的更一般的父类,如动物类,它们都有奔跑的能力。几维鸟的飞行速度虽然为0,但奔跑速度不为 0。修改后的UML类如下所示。

第五步:添加 anmial.h

代码语言:javascript
复制
#pragma once//这个是必须的,不然子类没法引用的

class Animal
{
    public:
        void setspeed(double speed){this->_speed=speed;}
        double gettime(double dis){return dis/_speed;}
    private:
        double _speed;
};

第六步: 重新定义notbird_brownkiwi.h

代码语言:javascript
复制
#include "animal.h"
class NotBirdBrownKiwi: public Animal
{
};

第七步: 修改 main.cpp

代码语言:javascript
复制
 NotBirdBrownKiwi* bird2=new  NotBirdBrownKiwi();//调用的是子类的方法

结果显示:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档