可以扩展 C + + 中的类,即创建保留基类特征的新类。这个过程称为继承,涉及一个基类和一个派生类: 派生类继承基类的成员,在这些成员之上派生类可以添加自己的成员。
例如,让我们想象一系列的类来描述两种多边形: 矩形(rectangles)和三角形(triangles)。这两个多边形有一些共同的属性,例如计算它们的面积所需的值: 它们都可以简单地用高度和宽度(或基数)来描述。
这可以在类的世界中用一个Polygon
类来表示,我们可以从这个类派生出另外两个多边形: 矩形( Rectangle
)和三角形(Triangle
):
Polygon 类将包含多边形所具有的一些通用的成员。如在我们的例子中: 宽度和高度。矩形和三角形将是它的派生类,具有各自特定特征。
从其他类派生的类继承基类的所有可访问成员。这意味着如果一个基类包含一个成员 A,并且我们从它派生一个包含另一个成员 B 的类,那么派生的类将同时包含成员 A 和成员 B。
两个类的继承关系在派生类中声明:class derived_class_name: public base_class_name { /*...*/ };
derived_class_name
是派生类的名称,base _ class _ name 是它所继承的基类的名称。公共访问说明符也可以由其他访问说明符(protected
或 private
)。- // 派生类
- #include
- using namespace std;
-
- class Polygon {
- protected:
- int width, height;
- public:
- void set_values (int a, int b)
- { width=a; height=b;}
- };
-
- class Rectangle: public Polygon {
- public:
- int area ()
- { return width * height; }
- };
-
- class Triangle: public Polygon {
- public:
- int area ()
- { return width * height / 2; }
- };
-
- int main () {
- Rectangle rect;
- Triangle trgl;
- rect.set_values (4,5);
- trgl.set_values (4,5);
- cout << rect.area() << '\n';
- cout << trgl.area() << '\n';
- return 0;
- }
Polygon类
继承的成员,这些对象是: width、 height 和 set _ value。private
访问说明符类似于 private。其唯一的区别实际上与继承有关: 当一个类继承另一个类时,派生类的成员可以访问从基类继承的private
成员,但不能访问其私有(private)成员。
我们可以总结出不同的访问类型,根据这些类型,函数可以通过以下方式访问它们:
访问 | public | protected | private |
---|---|---|---|
类内成员 | yes | yes | yes |
派生类成员 | yes | yes | no |
非成员 | yes | no | no |
在上面的示例中,由矩形和三角形继承的成员拥有与其基类 Polygon 相同的访问权限:
- Polygon::width // protected access
- Rectangle::width // protected access
-
- Polygon::set_values() // public access
- Rectangle::set_values() // public access
class Rectangle: public Polygon { /* ... */ }
使用 protected 时,基类的所有公共(public)成员在派生类中继承为 protected。相反,如果指定了最受限制的访问级别(private) ,则所有基类成员都将作为 private 继承。
例如,如果daughter是从mother派生的类,我们定义为:
class Daughter: protected Mother;
原则上,公共派生类继承基类的每个成员,除了:
即使对基类的构造函数和析构函数的访问不是继承的,它们也会被派生类的构造函数和析构函数自动调用。
除非另有说明,否则派生类的构造函数将调用其基类的默认构造函数(即不带参数的构造函数)。使用初始化列表中用于初始化成员变量的相同语法,可以调用基类的另一个构造函数:
derived_constructor_name (parameters) : base_constructor_name (parameters) {...}
例如:
- // 构造函数与派生类 || constructors and derived classes
- #include
- using namespace std;
-
- class Mother {
- public:
- Mother ()
- { cout << "Mother: no parameters\n"; }
- Mother (int a)
- { cout << "Mother: int parameter\n"; }
- };
-
- class Daughter : public Mother {
- public:
- Daughter (int a)
- { cout << "Daughter: int parameter\n\n"; }
- };
-
- class Son : public Mother {
- public:
- Son (int a) : Mother (a)
- { cout << "Son: int parameter\n\n"; }
- };
-
- int main () {
- Daughter kelly(0);
- Son bud(0);
-
- return 0;
- }
输出结果:
Mother: no parameters Daughter: int parameter Mother: int parameter Son: int parameter
请注意在创建新的 Daughter 对象时调用 Mother 的构造函数与在创建 Son 对象时调用 Mother 的构造函数之间的区别。区别在于 Daughter 与 Son 的构造函数声明不同:
Daughter (int a) //
没有特别说明: 调用默认构造函数
Son (int a) : Mother (a) //
调用这个特定的构造函数(有参构造)
一个类可以通过简单地指定更多的基类(用逗号分隔)来继承不止一个类。例如,再继承在屏幕上打印 Output 的特定类,我们可以写:
class Rectangle: public Polygon, public Output;
class Triangle: public Polygon, public Output;
完整的示例:
- // 多重继承 || multiple inheritance
- #include
- using namespace std;
-
- class Polygon {
- protected:
- int width, height;
- public:
- Polygon (int a, int b) : width(a), height(b) {}
- };
-
- class Output {
- public:
- static void print (int i);
- };
-
- void Output::print (int i) {
- cout << i << '\n';
- }
-
- class Rectangle: public Polygon, public Output {
- public:
- Rectangle (int a, int b) : Polygon(a,b) {}
- int area ()
- { return width*height; }
- };
-
- class Triangle: public Polygon, public Output {
- public:
- Triangle (int a, int b) : Polygon(a,b) {}
- int area ()
- { return width*height/2; }
- };
-
- int main () {
- Rectangle rect (4,5);
- Triangle trgl (4,5);
- rect.print (rect.area());
- Triangle::print (trgl.area());
- return 0;
- }
输出结果:
20 10