接口继承与实现继承

继承可以从两方面理解:

1接口继承,只继承函数的接口(声明),需要在派生类中定义继承过来的纯虚函数。

2实现继承,同时继承接口与实现,可以重新定义继承的函数,也可以不重新定义。另外还有:子类不能重新定义继承的函数,这类函数就是普通的函数,非虚函数。


class Animal {
	public:
		virtual void attack()=0;
		virtual void getClass() {
			cout<<"Animal"<<endl;
		}
};
class Tiger:public Animal{
	public:
		void attack() {
			cout<<"Tiger Attack"<<endl;
		}
		void getClass() {
			cout<<"Tiger"<<endl;
		}
};

接口继承:

        比如上面两个类,Animal类attack函数是纯虚函数,这使得Animal是一个抽象类,无法实例化(即使为纯虚函数提供了定义也一样不能实例化)。对于动物种类有很多种,但是我们不知道他们的攻击方式比如抓、咬、毒液、捆绑等等。在定义Animal类的时候,我们并不知道应该如何来实现attack函数,所以将它声明为纯虚函数,由派生类来定义,即告诉子类”你必须提供一个attack函数,但我不知道你怎么去实现它“,定义纯虚函数的目的就是子类只继承函数的接口。

有时候声明一个只含有纯虚函数的类很有用,这种类称为协议类(Protocol Class),他只为子类提供接口,完全不提供实现。

实现继承:

        普通的虚函数和纯虚函数不一样,普通的虚函数一般提供了函数的实现,所以子类继承了函数的接口以及实现。但是子类可以选择重新定义或不定义这个函数而是用缺省实现。即告诉子类”你可以重新定义这个虚函数,或者使用缺省实现“。比如上面的getClass函数,可以重新定义,具体输出某个动物类别,也可以缺省实现而输出animal这个大类。

有了纯虚函数、简单虚函数和非虚函数,就可以决定子类继承哪种:仅接口继承、接口继承和缺省实现、接口继承和强制实现

两种极端:

1全都声明为非虚函数,这个问题从虚析构函数的必要性就可以看出,但是如果一个类永远不会作为基类,这么做也没错。

2全都声明为虚函数,有时这没问题,比如协议类就是这样的例子,但全是虚函数就代表派生类可以利用它来做任何事,这有时也会带来问题。

所以声明时应该慎重选择成员函数的种类。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值