Effective C++ 规则32:确定你的public继承塑模出is-a关系

        public继承应当是"is-a"的关系。当Derived public继承自Base时, 相当于你告诉编译器和所有看到你代码的人:Base是Derived的抽象,Derived就是一个Base,任何时候Derived都可以代替Base使用。Base class拥有的方法,在Derived对象调用起来仍然合理。

        书中给出了两个例子让读者加深印象,第一个例子代码如下:

class Bird{
public:
    vitural void fly();
};
class Penguin: public Bird{
    // fly??
};

        Penguin继承自Bird,但企鹅不会飞,

这时你可能会困惑Penguin到底是否应该有fly()方法。但其实这个问题来源于自然语言的二义性: 严格地考虑,鸟会飞并不是所有鸟都会飞。我们对会飞的鸟单独建模便是:

class Bird{...};
class FlyingBird: public Bird{
public:
    virtual void fly();
};
class Penguin: public Bird{...};

        这样当你调用penguin.fly()时便会编译错。当然另一种办法是Penguin继承自拥有fly()方法的Bird, 但Penguin::fly()中抛出异常。这两种方式在概念是有区别的:前者是说企鹅不能飞;后者是说企鹅可以飞,但飞了会出错。哪种实现方式好呢?接口应当设计得不容易被误用,最好将错误从运行时提前到编译时。所以前者更好!

        第二个例子:

        根据学校中的知识,正方形是一种特殊的矩形。但是转换到OOP中是不正确的,代码如下,正方形对象s执行完makeBigger后,它的长和宽不相等了,然而makeBigger却破坏了正方形的属性, 所以正方形并不是一个矩形(因为矩形需要有这样一个性质:增加宽度时高度不会变。

class Rect{...};
void makeBigger(Rect& r){
    int oldHeight = r.height();
    r.setWidth(r.width()+10);
    assert(r.height() == oldHeight);
}
class Square: public Rect{...};
 
Square s;
assert(s.width() == s.height());
makeBigger(s);
assert(s.width() == s.height());

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值