继承与面向对象设计(1)public继承、区分接口继承与实现继承

(1)
public 继承意味着“is-a”的关系,但是有时候会有特殊情况,比如:企鹅是一种鸟,鸟会飞,所以我们以为代码是:

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

但是企鹅不会飞,在鸟类中有几种鸟不会飞,就像大多数算法没有回调这种功能,但有一些算法会有这种功能,这时候我们可以这样写:

class Bird{
    ...
};

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

class Penguin:public Bird{
    ...
};

这样写也有缺陷,对于一些软件系统而言不需要区分鸟会不会飞,如果软件系统主要处理鸟的其他特性,完全不在乎飞行就不需要这样写。这也反映出一个事实,世界上并不存在一个“适用于所有软件”的完美设计,所谓最佳设计,取决于系统希望做什么事。
另外两种写法是:

a.
class Penguin:public Bird{
public:
    virtual void fly() { 
        error { "wrong!" };
    }
    ...
};
b.
不能为penguin定义fly函数
class Bird {
    ...
};

class Penguin:public Bird {
    ...
};

如果让企鹅飞就会报错:
Penguin p;
p.fly();

相比于第一种方法,第二种会更好,因为好的接口可以防止无效代码通过编译,相比于在运行时报错,在编译时报错会更好。
“public 继承”意味着“is-a”。适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象。

(2)
区分接口继承和实现继承;
a.pure virtual 函数只具体指定接口继承;
b.impure virtual函数具体指定接口继承及缺省实现继承;
c.non-virtual函数具体指定接口继承以及强制性实现继承;
关于b有时会有一种错误,如果子类没有自己重写impure virtual函数,就会自动调用基类的impure virtual缺省实现,如果子类的实现跟基类一样还好,如果不一样就会出错。所以有一种改进方法是把基类的impure virtual函数改为pure virtual函数,强制子类自己实现,基类的缺省改为protected下的函数,子类的实现如果和基类一样就可以在子类的实现中inline调用基类protected下的函数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值