对象(Object)是类(Class)的一个实例(Instance)。如果将对象比作房子,那么类就是房子的设计图纸。所以面向对象设计的重点是类的设计,而不是对象的设计。
对于C++程序而言,设计孤立的类是比较容易的,难的是正确设计基类及其派生类。本章仅仅论述“继承”(Inheritance)和“组合”(Composition)的概念。
注意,当前面向对象技术的应用热点是COM和CORBA,这些内容超出了C++教材的范畴,请阅读COM和CORBA相关论著。
继承
如果A是基类,B是A的派生类,那么B将继承A的数据和函数。例如:
class A
{
public:
voidFunc1(void);
voidFunc2(void);
};
class B : public A
{
public:
voidFunc3(void);
voidFunc4(void);
};
main()
{
Bb;
b.Func1();// B从A继承了函数Func1
b.Func2();// B从A继承了函数Func2
b.Func3();
b.Func4();
}
这个简单的示例程序说明了一个事实:C++的“继承”特性可以提高程序的可复用性。正因为“继承”太有用、太容易用,才要防止乱用“继承”。我们应当给“继承”立一些使用规则。
l【规则10-1-1】如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能和属性。不要觉得“白吃白不吃”,让一个好端端的健壮青年无缘无故地吃人参补身体。
l【规则10-1-2】若在逻辑上B是A的“一种”(a
kind of),则允许B继承A的功能和属性。例如男人(Man)是人(Human)的一种,男孩(Boy)是男人的一种。那么类Man可以从类Human派生,类Boy可以从类Man派生。
class Human
{
…
};
class Man : public Human
{
…
};
class Boy : public Man
{
…
};
u注意事项
【规则10-1-2】看起来很简单,但是实际应用时可能会有意外,继承的概念在程序世界与现实世界并不完全相同。
例如从生物学角度讲,鸵鸟(Ostrich)是鸟(Bird)的一种,按理说类Ostrich应该可以从类Bird派生。但是鸵鸟不能飞,那么Ostrich::Fly是什么东西?
class Bird
{
public:
virtual void Fly(void);
…
};
class Ostrich : public Bird
{
…
};
例如从数学角度讲,圆(Circle)是一种特殊的椭圆(Ellipse),按理说类Circle应该可以从类Ellipse派生。但是椭圆有长轴和短轴,如果圆继承了椭圆的长轴和短轴,岂非画蛇添足?
所以更加严格的继承规则应当是:若在逻辑上B是A的“一种”,并且A的所有功能和属性对B而言都有意义,则允许B继承A的功能和属性。
l【规则10-2-1】若在逻辑上A是B的“一部分”(a
part of),则不允许B从A派生,而是要用A和其它东西组合出B。
例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类Eye、Nose、Mouth、Ear组合而成,不是派生而成。如示例10-2-1所示。
class Eye
{
public:
voidLook(void);
};
|
class Nose
{
public:
voidSmell(void);
};
|
class Mouth
{
public:
voidEat(void);
};
|
class Ear
{
public:
voidListen(void);
};
|
//正确的设计,虽然代码冗长。
class Head
{
public:
voidLook(void){m_eye.Look();}
voidSmell(void){m_nose.Smell();}
voidEat(void){m_mouth.Eat();}
voidListen(void){m_ear.Listen();}
private:
Eyem_eye;
Nosem_nose;
Mouthm_mouth;
Earm_ear;
};
|
示例10-2-1Head由Eye、Nose、Mouth、Ear组合而成
如果允许Head从Eye、Nose、Mouth、Ear派生而成,那么Head将自动具有Look、Smell、Eat、Listen这些功能。示例10-2-2十分简短并且运行正确,但是这种设计方法却是不对的。
//功能正确并且代码简洁,但是设计方法不对。
class Head : public Eye, public Nose, public Mouth, public Ear
{
};
|
示例10-2-2Head从Eye、Nose、Mouth、Ear派生而成
一只公鸡使劲地追打一只刚下了蛋的母鸡,你知道为什么吗?
因为母鸡下了鸭蛋。
很多程序员经不起“继承”的诱惑而犯下设计错误。“运行正确”的程序不见得是高质量的程序,此处就是一个例证。
对象(Object)是类(Class)的一个实例(Instance)。如果将对象比作房子,那么类就是房子的设计图纸。所以面向对象设计的重点是类的设计,而不是对象的设计。
对于C++程序而言,设计孤立的类是比较容易的,难的是正确设计基类及其派生类。本章仅仅论述“继承”(Inheritance)和“组合”(Composition)的概念。
注意,当前面向对象技术的应用热点是COM和CORBA,这些内容超出了C++教材的范畴,请阅读COM和CORBA相关论著。
继承
如果A是基类,B是A的派生类,那么B将继承A的数据和函数。例如:
class A
{
public:
voidFunc1(void);
voidFunc2(void);
};
class B : public A
{
public:
voidFunc3(void);
voidFunc4(void);
};
main()
{
Bb;
b.Func1();// B从A继承了函数Func1
b.Func2();// B从A继承了函数Func2
b.Func3();
b.Func4();
}
这个简单的示例程序说明了一个事实:C++的“继承”特性可以提高程序的可复用性。正因为“继承”太有用、太容易用,才要防止乱用“继承”。我们应当给“继承”立一些使用规则。
l【规则10-1-1】如果类A和类B毫不相关,不可以为了使B的功能更多些而让B继承A的功能和属性。不要觉得“白吃白不吃”,让一个好端端的健壮青年无缘无故地吃人参补身体。
l【规则10-1-2】若在逻辑上B是A的“一种”(a
kind of),则允许B继承A的功能和属性。例如男人(Man)是人(Human)的一种,男孩(Boy)是男人的一种。那么类Man可以从类Human派生,类Boy可以从类Man派生。
class Human
{
…
};
class Man : public Human
{
…
};
class Boy : public Man
{
…
};
u注意事项
【规则10-1-2】看起来很简单,但是实际应用时可能会有意外,继承的概念在程序世界与现实世界并不完全相同。
例如从生物学角度讲,鸵鸟(Ostrich)是鸟(Bird)的一种,按理说类Ostrich应该可以从类Bird派生。但是鸵鸟不能飞,那么Ostrich::Fly是什么东西?
class Bird
{
public:
virtual void Fly(void);
…
};
class Ostrich : public Bird
{
…
};
例如从数学角度讲,圆(Circle)是一种特殊的椭圆(Ellipse),按理说类Circle应该可以从类Ellipse派生。但是椭圆有长轴和短轴,如果圆继承了椭圆的长轴和短轴,岂非画蛇添足?
所以更加严格的继承规则应当是:若在逻辑上B是A的“一种”,并且A的所有功能和属性对B而言都有意义,则允许B继承A的功能和属性。
l【规则10-2-1】若在逻辑上A是B的“一部分”(a
part of),则不允许B从A派生,而是要用A和其它东西组合出B。
例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head应该由类Eye、Nose、Mouth、Ear组合而成,不是派生而成。如示例10-2-1所示。
class Eye
{
public:
voidLook(void);
};
|
class Nose
{
public:
voidSmell(void);
};
|
class Mouth
{
public:
voidEat(void);
};
|
class Ear
{
public:
voidListen(void);
};
|
//正确的设计,虽然代码冗长。
class Head
{
public:
voidLook(void){m_eye.Look();}
voidSmell(void){m_nose.Smell();}
voidEat(void){m_mouth.Eat();}
voidListen(void){m_ear.Listen();}
private:
Eyem_eye;
Nosem_nose;
Mouthm_mouth;
Earm_ear;
};
|
示例10-2-1Head由Eye、Nose、Mouth、Ear组合而成
如果允许Head从Eye、Nose、Mouth、Ear派生而成,那么Head将自动具有Look、Smell、Eat、Listen这些功能。示例10-2-2十分简短并且运行正确,但是这种设计方法却是不对的。
//功能正确并且代码简洁,但是设计方法不对。
class Head : public Eye, public Nose, public Mouth, public Ear
{
};
|
示例10-2-2Head从Eye、Nose、Mouth、Ear派生而成
一只公鸡使劲地追打一只刚下了蛋的母鸡,你知道为什么吗?
因为母鸡下了鸭蛋。
很多程序员经不起“继承”的诱惑而犯下设计错误。“运行正确”的程序不见得是高质量的程序,此处就是一个例证。
分享到:
相关推荐
第10条 尽量减少全局和共享数据 19 第11条 隐藏信息 20 第12条 懂得何时和如何进行并发性编程 21 第13条 确保资源为对象所拥有。使用显式的RAII和智能指针 24 编程风格 27 第14条 宁要编译时和连接...
#### 第10章 类的继承与组合 **10.1 继承** - 继承是一种使类可以从已有类获取属性和行为的方式。 - 通过继承可以实现代码复用和多态。 **10.2 组合** - 组合是通过将一个对象作为另一个对象的成员来实现的。 - ...
第10章 类的继承与组合 本章解释了继承和组合的概念以及它们在面向对象编程中的应用。 第11章 其他编程经验 本章分享了使用CONST提高函数健壮性的技巧、提高程序效率的建议以及其他有益的编程经验。 参考文献 书末...
【Google C++编程规范指南简介】是一份针对C++编程的规范文档,旨在提升代码质量、可读性和可维护性,特别关注了C++语言的高效特性与复杂性之间的平衡。以下是规范中的关键知识点: 1. **代码风格**:代码风格关乎...
该文档为Google公司内部使用的C++编程规范指南,旨在提高代码的一致性与可维护性,同时也适用于其他使用C++进行软件开发的团队和个人。 #### 三、头文件规范 - **#define保护**: 使用`#ifndef`、`#define`及`#endif...
《高质量C++/C编程指南》是由林锐博士撰写,旨在为读者提供高质量的软件开发方法和C++/C编程规范。本书不仅包含了软件质量和面向对象程序设计方法的深入讨论,还涉及了C++/C编程风格以及一些技术专题。 书中将软件...
《Visual C++程序设计案例教程》是学习C++编程的重要参考资料,由张荣梅老师编著,本部分主要涵盖的是第一章的源代码。在第一章中,通常会介绍C++的基础知识,包括C++语言的历史、环境搭建、第一个“Hello, World!”...
以下是一些关键的C++编程规范知识点: 1. **命名规则**:采用有意义的标识符,如变量、函数、类名等,应清晰反映它们的用途。遵循驼峰命名法(CamelCase)或下划线命名法(snake_case),保持一致性。 2. **注释**...
《编程艺术-C++》这本书深入探讨了C++编程语言的艺术与科学,旨在帮助读者掌握C++的核心概念和最佳实践。本书包含丰富的代码示例和详细解释,为初学者和有经验的开发者提供了全面的指导。 C++是一种多范式、静态...
#### 第10章 类的继承与组合 - **继承**:利用继承机制来实现代码复用,但要注意避免过度使用。 - **组合**:通过组合对象来构建复杂的类结构,从而提高代码的可维护性和扩展性。 #### 第11章 其它编程经验 - **...
#### 第10章 类的继承与组合 - **继承**:阐述了继承的概念及其在类设计中的应用。 - **组合**:介绍了组合的概念及其与继承的比较。 #### 第11章 其他编程经验 - **使用CONST提高函数的健壮性**:解释了如何通过...
### Google C++编程规范知识点概览 #### 一、头文件 在Google C++编程规范中,关于头文件的部分强调了几个重要的方面: 1. **`#define` 的保护**:为了避免同一个头文件被多次包含导致的问题(如重复定义等),...
### C++编码规范 #### 第1章 命名原则 **原则1.1 关于类型名** - 类型名称应当清晰明确,避免使用容易混淆的名称。 - 示例:`int` 类型不应命名为 `Int` 或 `i`。 **原则1.2 关于变量和函数名** - 变量和函数名应...
第10章讲述了类的继承与组合,这是面向对象编程的核心概念,通过继承和组合可以构建复杂的类层次结构。 第11章提供了一些其他的编程经验,如使用CONST提高函数健壮性、提升程序效率的技巧,以及一些有益的建议,...
### C++编程规范知识点 #### 一、C++编程规范概览 本文档详细阐述了北京中创信测科技股份有限公司内部对于C++编程的具体规范,旨在通过统一编码风格和实践来提升代码的质量与可维护性。 #### 二、适用范围 此...
#### 第10章 类的继承与组合 - **继承**:类继承的基础概念及其优缺点。 - **组合**:使用组合而非继承的原则和方法。 #### 第11章 其它编程经验 - **使用const提高函数的健壮性**:const关键字的使用技巧。 - **...