C++学习笔记----9、发现继承的技巧(一)---- 使用继承构建类(2)
1.2、继承的继承类的视角
对于继承来说,在如何书写与如何行为方面没有什么变化。仍然可以定义成员函数与成员变量在继承类上与在通常的类上一样。前面Derived的定义声明了一个叫做someOtherFunction()的成员函数。这样,Derived通过添加另外一个成员函数增大了Base类。
继承类可以访问在基类中的公共的与受保护的成员函数与数据成员就像它自己的一样,因为从技术上来说它就是。例如,Derived上的someOtherFunction()的实现可以使用数据成员m_protectedInt,它就是Base声明的一部分。下面的代码展示了这一点。访问基类成员与作为继承类的一部分声明的成员没有什么不同。
void someOtherFunction(){println("I can access base class data member m_protectedInt.");println("Its value is {}", m_protectedInt);}
如果一个类声明其成员为受保护的,继承类可以访问它们。如果它们被声明为私有的,继承类就不能访问它们。下面的someOtherFunction()编译不成功,因为继承类尝试去访问基类中的私有数据成员:
void someOtherFunction(){println("I can access base class data member m_protectedInt.");println("Its value is {}", m_protectedInt);println("The value of m_privateInt is {}", m_privateInt); // Error!}
私有访问指示符给了你控制如何与潜在的继承类交互的能力。
我们前面提到过如下的规则:所有的数据成员都应该是私有的,如果想从类外部访问数据成员要提供公共的getter与setter。这个规则可以延伸到包括受保护的访问指标符。
警告:所有的数据成员都应该是私有的,如果想从类外部访问数据成员要提供公共的getter与setter。如果只想继承类来访问它们要提供受保护的getter与setter。
缺省使数据成员为私有的原因是提供更高级别的封装。这意味着在保持公共与受保护的接口不变的情况下改变提供数据的方式。还有,在不提供直接访问数据成员的情况下,可以容易地对公共和受保护的setter中输入的数据加以检查。成员函数缺省也应该是私有的。只有在设计时就是公共的情况下才会使那些成员函数为公共的,如果想让继承类可以访问它们才会让成员函数为受保护的。
注意:从继承类的角度,所有基类中的公共与受保护的数据成员与成员函数都是可用的。
下表总结了三个访问指示符的意思:
访问指示符 | 意思 | 何时使用 |
public | 任何代码都可以调用对象的public成员函数与访问public数据成员 | 想让客户使用的行为(成员函数)。 对于private与protected数据成员访问成员函数(getter与setter) |
protected | 任何类的成员函数都可以调用protected成员函数与访问protected数据成员。 继承类的成员函数可以访问基类的protected成员 | 不想让客户使用“Helper”成员函数。 |
private | 只有类的成员函数可以调用private成员函数,访问private数据成员。继承类的成员函数无法访问基类的private成员。 | 所有的都应该缺省为private,特别是数据成员。如果只想允许继承类访问它们,可以提供protected getter与setter,如果想让客户访问它们可以提供public getter与setter。 |
1.3、禁止继承
c++允许将类标识成final,意味着尝试去继承它的话就会报编译错误。类可以在类名的后面用final关键字标识成final。例如,如果一个类尝试去从下面的Foo类进行继承,编译器会产生一个错误:
class Foo final { };