继承
谈到继承就不能不先说说public,protected,private:
(1) Public成员:
1. 在类内部:可直接使用,可以通过(类的对象,指针,引用------以后称之为类的形象代言人)访问。
2. 类外部:可以通过类的形象代言人访问。
(2) Protected成员:
1. 在类内部:直接使用+形象代言人访问。
2. 在类外部:无法访问。可以通过public接口间接访问。
(3) Private成员:
1. 在类内部:直接使用+形象代言人访问。
2. 在类外部:无法访问。可以通过public接口间接访问。
(4) 友元(非类成员): 友元函数是全局的,所以没有public等之分。且友元函数必须要有一个该类的类型参数(名字查找有关)。
这样就可以在友元函数中通过类的形象代言人访问protected/private成员。
友元类同样无public/protected/private之分。看一个例子:
|
输出: 10 10 10 100 100 100 B是A的友元,那么B中可以通过A的形象代言人访问A的私有成员。 |
特别提醒:对于形象代言人来说,只有本类内部才算类内部,即使派生类内部也算是基类形象代言人的类外部。
Public继承:是一种用的最多的继承方式。
被继承的基类成员访问权限如下:(public,protected,private特性不变)
(1) public成员:在派生类中具有父类同等的访问权限,与派生类本身的public无异。
(2) protected成员:在派生类中继承了该部分成员,说明儿子具备了父亲的protected成员所描述某种特质,但是并不代表儿子可以访问父亲的这些特质。他只能访问继承过来的属于自己的特质。所以在派生类中可以直接访问继承过来的已经属于自己的protected,但是无法通过父类的形象代言人访问父类的protected成员。换句话说对于父类的形象代言人来说派生类中是父类的类外部。当然形象代言人可以通过父类的公有接口间接访问受保护成员。
(3) private成员:在派生类中无法访问,可以通过父类的公有接口间接访问(前题是父类实现了这些接口)。
(4) 在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。
<C++ Primer 4th>中写到:(1)用户代码可以访问类的public成员,而不能访问类的private成员。(2)private只能由基类的成员和友元访问。(3)派生类对基类的访问权限和用户代码相同:可以访问基类的public成员但是无法访问private成员。(以上不适用于protected成员)
(5) 有时作为基类的类具有一些成员,它希望允许派生类访问但仍禁止其他用户访问这些成员。这时我们就需要protected成员。
提醒:友元关系不可继承。
Protected继承:用的不多,可用于继承部分接口(网友观点)。
被继承的基类成员访问权限如下:(public,protected,private特性改变)
(1) public成员:变成portected成员,派生类内部可以访问,但外部不可访问。父类的形象代言人可访问。
(2) protected成员:不变,内部可以访问,外部不能访问,父类形象代言人不可访问。
(3) private成员:不变,类内部不可访问。
接口部分继承:
|
这样我就B只是拥有接口interfaceA()了.从这个例子我们可以看出继承重写override是可以改变成员可见性的。不破坏多态。其实继承部分接口也可以这样(如下)。 |
|
这与上面的效果相同。对于不破坏多态性,我们来看一个有趣的例子。 |
|
输出: show. show in B. |
不但没有破坏多态,居然通过多态实现了调用子类的私有成员函数。 |
新的设计思路:通过上述例子我们发现我们可以实现一个父类,然后它有一堆子类,我们可以通过改变接口的访问属性为protected/private或者实现protected/private继承来实现子类无法访问自己的接口,却可以通过多态来实现父类对子类的统一管理。
Private继承:很少使用,和protected继承一样是一种实现继承。
被继承的基类成员访问权限如下:(public,protected,private特性改变)
(1)全都变为private:原基类中的public和protected在类中可以访问,类外部不可以访问。private不可访问。
(2)父类的形象代言人拥有用户代码权限。
总结:类成员的访问权限可以归结为两类,类权限和用户代码权限。类权限:在本类内部(仅限于本类内部)的权限。用户代码权限:在类外(包括其派生类内部)通过形象代言人访问的权限。
对于public,protected,private成员的继承我们可以用一个比方描述其权限改变情况。(适用于public继承)
基类/父类:父亲
派生类/子类:儿子
方法:武功
接口:用于厮杀的武功
保护成员:修练内力的功夫
私有成员:武林秘籍(放在魔法盒中)
public/protected/private接口:打开魔法盒的咒语
父亲是一位江湖人人敬仰的侠客,拥有绝世武功。有一些是别人能够能见到的,这些它会用于与人厮杀。有一些则是别人不知道的,或者别人无法看到的,比如<<易筋经>>,父亲只会在夜深人静,无人旁观的情况下才会用来修练内力(当然你是他的儿子,你可以看到,如果他教给(你继承)了你,你就会,当然你也不会让别人看到)。同时父亲还有一本武林秘籍,得此秘籍者得天下。由于这本秘籍异常珍贵,所以父亲将他存在魔法盒中,即使别人拿到了魔法盒,也无法打开它。如果你的父亲是一位很爱炫耀的侠士,那么它会选择在公众场合(public)念出咒语(当然这也无关紧要,因为只有拥有你们家族血统的人念出咒语才管用);当然你父亲也可以不这么做,他会在家里(protected)念出来。这样你们也就知道了。你学会了(继承了)就可以用了。如果你父亲很自私的话,他只会私下一个人的时候才会念出咒语(private),这样你永远也打不开父亲给你的盒子(只能做个念想了)。更有甚者,你父亲压根不制造这样一条咒语,因为如果这个盒子里全是它自己的东西的话,他是不需要咒语的,他用指纹就OK了(而指纹是无法继承的-----不在继承的范畴)。
这个魔法盒很奇特,它可以自我复制,但是却共用同一条咒语。当你继承了父亲的魔法盒后,如果你没有获得咒语你将无法打开。而且你本人也将拥有一个属于自己的魔法盒,如果你父亲的咒语是protected的,那么你父亲给你的魔法盒会放在其中。当你的子孙想要打开你父亲的魔法盒时,必须先打开你的魔法盒,然后再打开你父亲的魔法盒。也就是你需要提供咒语来启用你父亲的咒语。如果你父亲的咒语是public那么你的盒子和他给你的盒子将是并排放着的。你的子孙可以直接用你父亲的咒语打开你继承自父亲的盒子。打开你的盒子自然是用你提供的咒语。
小结:结合多态+protected/private我们可以实现由父类统一管理子类,并禁止子类调用任何接口的设计。
|
私有继承当然也有别的作用,但是不是非不得已,我们可以用组合来实现。见下文:
http://blog.csdn.net/liaoyoujinb/article/details/14450063