1,public继承分为两类:接口继承和实现继承.
这两种继承的差异类似于函数声明和函数继承的差异.
2,你的可能需求:
(1)希望只继承基类的接口;
(2)希望继承基类的接口和实现,而且可以改写它们.
(3)希望继承基类的接口和实现,但是不允许改写它们.
3,例子:
class Shape
{
public:
virtual void draw() const = 0;
virtual void error(const string& msg);
int objectID() const;
...
};
class Rectangle: public Shape { ... };
class Ellipse: public Shape { ... };
4,先看纯虚函数draw.
纯虚函数的两个突出特性:(1)它们必须被"继承了它们"的具体类重新声明;(2)它们在抽象类中通常没有定义.
那么可以得到:
声明一个纯虚函数的目的是为了让derived class只继承其接口.
注:但是我们可以为纯虚函数提供定义,你可以为Shape:draw供应一份实现代码.
如:
Shape *ps1 = new Rectangle; // fine
ps1->draw(); // calls Rectangle::draw
ps1->Shape::draw(); // 但是只能通过完整名称调用,虚基类无法生成对象.
5,再看一般的虚函数.
传统上会给出一份实现,derived class可以自行选择要不要加以改写(override).
声明一般虚函数的目的:
是为了让derived class继承该函数的接口和缺省行为.
6,看一个现实的例子:
class Airport { ... }; // represents airports
class Airplane
{
public:
virtual void fly(const Airport& destination);
...
};
void Airplane::fly(const Airport& destination)
{
default code for flying an airplane to
the given destination
}
class ModelA: public Airplane { ... };
class ModelB: public Airplane { ... };
fly缺省的行为同时被ModelA和ModelB继承,避免程序代码重复.
但是如果继续ModelC,可能导致:
"没有明白说我要"的情况下,ModelC继承了该缺省行为.
下面给出一个精巧的实现:
class Airplane //这里设为纯虚函数
{
public:
virtual void fly(const Airport& destination)=0;
...
};
void Airplane::fly(const Airport& destination)
{
default code for flying an airplane to
the given destination
}
//Derived class需要显式overridefly
class ModelA: public Airplane
{
virtual void fly(const Airport& destination)
{
Ariplane::fly(destination);
}
...
};
class ModelB: public Airplane
{
virtual void fly(const Airport& destination)
{
Ariplane::fly(destination);
}
...
};
class ModelC: public Airplane
{
virtual void fly(const Airport& destination)
{
自己的实现
}
...
};
7,声明非虚拟函数的目的:
为了令Derived class继承函数的接口和实现.
注:非虚拟函数代表的意义"不变形"凌驾于"变异性"之上,我们不应该在Derived class中重新定义它.
分享到:
相关推荐
条款36: 区分接口继承和实现继承 条款37: 决不要重新定义继承而来的非虚函数 条款38: 决不要重新定义继承而来的缺省参数值 条款39: 避免 "向下转换" 继承层次 条款40: 通过分层来体现 "有一个" 或 "用...来实现" ...
**条款36:区分接口继承和实现继承** - **目的**: 区分不同类型的关系。 - **解释**: 接口继承指的是只继承接口而不需要关心具体实现,而实现继承则是继承了具体的实现。在设计时,应该根据实际需求来区分这两种...
条款34:区分接口继承和实现继承 条款35:考虚virtual函数以外的其他选择 条款36:绝不重新定义继承而来的non-virtual函数 条款37:绝不重新定义继承而来的缺省参数值 条款38:通过复合塑模出has-a或“根据某物...
条款34:区分接口继承和实现继承 differentiate between inheritance of interface and inheritance of implementation. 条款35:考虑virtual函数以外的其他选择 consider alternatives to virtual functions. 条款...
3. **财产性质的认定**:遗产中区分了婚前财产和婚后财产,婚前财产一般视为个人财产,婚后财产则可能涉及夫妻共同财产的概念。协议书中提及的银行存款、房产等财产,需根据婚姻状况来判断归属。 4. **放弃继承权**...
6. 辩论遗产继承方式,区分法定继承和遗嘱继承,明确继承原则和顺序。 7. 分析未成年人的财产继承权,以刘某的遗嘱为例,探讨合法性和教育意义。 【活动】: 1. “你知道吗?”活动,介绍宪法关于经济权利的条款,...
- **条款33至36**:讨论了继承中命名冲突的避免、非虚函数的重定义问题以及默认参数值的继承规则。 - **条款38**:介绍了复合(composition)作为一种替代继承的方式,用于表达“has-a”或“is-implemented-in-terms...
- **继承**:了解继承的基本概念,如何实现和维护继承关系。 - **组合**:通过组合其他类的对象来扩展功能,而不是通过继承。 #### 十一、其它编程经验 - **使用const提高健壮性**:通过const限定符限制修改,提高...
文档中通过"Joe"对继承的思考以及对接口的讨论,体现了在软件设计中对继承和接口选择的权衡。继承是面向对象编程中实现代码复用的一种手段,但它也可能导致代码的紧耦合。接口则提供了一种更加松散的依赖关系,使得...
封装可以隐藏对象的内部状态和实现细节,只保留对外提供的操作接口。继承允许一个类继承另一个类的属性和方法,从而可以重用代码并构建层次化的类结构。多态则允许使用同一接口来引用不同类的对象,使得不同的类可以...
【文档标题】主要探讨了合同规范在格式条款规制中的范式作用,即法律规定的本质性和根本思想在格式条款中的体现和约束。【描述】并未给出具体信息,但可以推测与文档标题一致,讨论合同法在格式条款设定中的规范作用...
- **按客户价值分类**: 区分VIP客户、主要客户、普通客户和小客户。 #### 十、客户关系生命周期 - **建立期**: 初次接触客户并建立基本信任。 - **加强期**: 深化与客户的互动,提升客户满意度。 - **维持期**: ...
- 正常服务、附加服务和额外服务有明确的区分,其中额外服务是在正常和附加服务之外,根据第28条需要履行的。 - 监理工程师需尽职尽责,运用专业技能,并在行使权力或履行职责时保持公正。 4. **业主的义务**: ...
总结来说,此大纲要求考生对民法体系有深入理解,掌握物权、债权的运作机制,熟悉合同法的具体条款,了解人身权的法律保护,理解继承权的法律规定,并能够分析和解决相关的民事责任问题。考生需广泛阅读并深入研究...