第六部分 继承与面向对象设计 条款32:确定你的public继承是is-a关系

     以C++进行面向对象编程,有一个重要的规则,public继承意味着是is-a关系,所谓is-a就是一种 的意思。比如我们用Person为基类,Student为派生类实现public继承。每个Student都是Person,但是每个Person不一定都是Student。在继承体系中,任何函数如果愿意接受一个Person的实参,那么也愿意接受一个Student的对象。

如:void eat(const Person& p);//可以接受Student,反过来就不行了。

另外一个例子:

 class Bird

{

   public:

    virtual void fly();  //鸟可以飞

   ...

};

class Penguin:public Bird  //企鹅是一种鸟

{

...

};

但是这里企鹅是不能够飞的呀!所以这不是is-a的关系!改进下:

 class Bird

{

   public:

   ...

};

class FlyingBird:public Bird

{

   public:

   virtual void fly();

  ....

};

class Penguin:public Bird  //企鹅是一种鸟

{

...

};

这个继承体系更能够反应出真实性。但是我们并不能够完全处理好这些事情,软件的设计要根据你的需求来定。

另外的方法:

void error(const  std::string& msg); 

class Penguin:public Bird

{

   public:

      virtual void fly(){ error("Attempt to make a Penguin fly!");}

  ....

};

这样做如果fly的话会导致运行期间的错误,但是我们希望编译期间出错。书中写到子类父类都不声明这个fly可以编译出错,但是我觉得过于牵强,你父类都没有声明这个函数,那么继承体系都也就不存在这个fly行为了,还谈什么客户会调用呢。

书中另外一个例子是矩形和正方形的继承设计:

class Rect

{

  public:

     virtual void setHeigh(int newH);

    virtual void setWidth(int setW);

    virtual int height() const;

    virtual int width() const;

  .....

};

void makeBigger(Rect& r)

{

   int oldH = r.height();

   r.setWidth(r.width()+10);

  assert(r.height()==oldH);

}

很明显assert为真,因为height没有改变

现在继承;

class Sq;public Rect{.........};

Sq s;

....

assert(s.width()==s.height());对于所有的正方形为真

makeBigger(s);

assert(s.width()==s.height());

第二个assert也肯定为真。因为正方形的高度宽度必须相等

但是实际上这里是有问题的。make之前相等,make函数内s的宽度改变了 实际上他们根本就不相等。

public继承要求能够使用与基类的东西也可以用于派生类。但是这里是不行的,所以不符合public继承。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值