继承
继承
@(C++)
面向对象编程基于那几个方面?[1]
继承部分要学主要的内容:
- 编程意义上的继承、以
及继承的意义 - C++的继承语法
- 公有继承、私有继承、保护继承、多继承
- 隐藏基类方法、切除导致的问题
继承基础
生物学的分类最能清晰地体现继承概念。单词derive作“继承自,起源于...”的意思时用被动语态 be derived。所以,继承的基础语法class Base: access-specifier Base ,中文意思就是:*** 当前基类是从另外一个基类衍生来的。衍生与继承,在这里是一样的意思。Note:遇到简单的概念,不要去想里面有什么高深的东西,这不是科学探索,只是在学习已有的框架*。所以,继承就只是这样而已。最简单的概念。虽然这个概念还有各种情况要区分,但是,在一开始只需要最直观的理解即可。
访问限定符: protected
保护继承特性
- 不能在类层次之外调用被保护的成员。
比如
myLunch.FreshWaterFish = false;
不能通过调用,即使myLunch是从Fish衍生而来的Carp的对象。但是这条语句是在main()中调用的,是在类层次之外的。
基类初始化——向基类传递参数
在派生类中可以对基类进行初始化,方法是通过派生类的构造函数调用基类的构造函数 。这可以在声明派生类的时候就确定派生类的某些未定量。这需要:
- 在基类中定义带参数和初始化列表的构造函数。
- 用派生类中的构造函数调用它
在基类中
...Fish(bool IsFreshWater) : FreshWaterFish(IsFreshWater);
在派生类中
...Tuna() : Fish(false);
在这里,从第二条语句输入的false的值将作为bool值传进构造函数Fish()中,然后通过初始化列表赋给bool变量FreshWaterFIsh。
基类和派生类的“方法覆盖”
这里的方法 = 函数 。有时候会出现这样一种情况:基类和派生类里面都定义了有相同名字的成员函数,而里面的内容不尽相同。
例子:
class Carp :public Fish;
class Tuna :public FIsh;
Fish、Carp、Tuna 都有Swim()这个重载函数。如何根据需要引用派生类或是基类里的Swim()呢?
Carp.Swim(); //引用派生类的
Carp.Fish::Swim(); //引用基类的
啰嗦一句:什么是“隐藏”
函数是可以重载 的,比如
//在基类中定义:
void Swim(){//可忽略的细节}
//以及:
void Swim(bool FreshWaterFish){//可忽略}
//在派生类中定义:
void Swim(){//...}
这样一来,就不能通过语句
//前面的实例化是:Tuna myDinner;
myDinner.Swim();
直接调用基类中的两个Swim了,这种情况就叫做隐藏。
不过,虽然被隐藏了,前两者还是可以通过 myDinner.Fish : : 函数名 进行调用的。不过,除了用作用域解析运算符(: : ) 之外,还有两种方法可以解除隐藏。详见注释。[2]
构造与析构顺序
私有继承
私有继承,语法上只是把public换成了private。
私有继承时,基类的所有数据和方法都是私有的,不能从外部访问。即便是基类的公有成员和方法,也只能被派生类使用。
保护继承
多继承
问答
练习
方法一:使用using关键字
方法二:在Tuna类中,覆盖Fish::Swim()的所有版本。
详见《21天学通C++》第七版165页。