面向对象编程中最重要的概念之一是继承。继承允许我们在另一个类的基础上定义一个类,这使得创建和维护应用程序变得更加容易。这也提供了一个重用代码功能和快速实现的机会。
在创建一个类时,程序员不必编写全新的数据成员和成员函数,而是可以指定新类应该继承现有类的成员。这个现有类被称为基类,而新类则被称为派生类。
继承实现了“is a”的关系。例如,哺乳动物“is a”动物,狗“is a”哺乳动物,因此狗也是动物。
基类与派生类
一个类可以从多个类派生,这意味着它可以继承来自多个基类的数据和函数。定义派生类时,我们使用类派生列表来指定基类。类派生列表命名一个或多个基类,并且形式如下:
class derived-class: access-specifier base-class
其中 access-specifier
是 public
、protected
或 private
中的一个,而 base-class
是先前定义的一个类。如果没有使用 access-specifier
,则默认为 private
。
考虑以下的基类 Shape
和其派生类 Rectangle
:
#include <iostream>
using namespace std;
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
class Rectangle: public Shape {
public:
int getArea() {
return (width * height);
}
};
int main(void) {
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
当以上代码被编译和执行时,它产生如下结果:
Total area: 35
访问控制与继承
派生类可以访问其基类的所有非私有成员。因此,基类中不应被派生类成员函数访问的成员应声明为私有。
我们可以总结不同访问类型的控制如下:
访问类型 |
同一类内 |
派生类 |
外部类 |
Public |
是 |
是 |
是 |
Protected |
是 |
是 |
否 |
Private |
是 |
否 |
否 |
派生类继承所有基类方法,除了以下几种例外:
继承类型
当从基类派生一个类时,基类可以通过 public
、protected
或 private
继承。继承类型由上面解释的 access-specifier
指定。
我们几乎不用 protected
或 private
继承,但 public
继承常用。使用不同类型的继承时,遵循以下规则:
-
公共继承:当从公共基类派生一个类时,基类的公共成员变为派生类的公共成员,基类的受保护成员变为派生类的受保护成员。基类的私有成员不能直接从派生类访问,但可以通过调用基类的公共和受保护成员来访问。
-
受保护继承:当从受保护基类派生时,基类的公共和受保护成员变为派生类的受保护成员。
-
私有继承:当从私有基类派生时,基类的公共和受保护成员变为派生类的私有成员。
多重继承
C++ 类可以使用多重继承从多个类继承成员。多重继承是一种允许一个类从多个基类继承的特性,这意味着派生类可以有多个父类,并且可以从所有基类继承属性和行为。
扩展的语法如下:
class derived-class: access baseA, access baseB...
其中 access
是 public
、protected
或 private
中的一个,并且每个基类都有一个 access
,它们之间用逗号分隔。让我们尝试以下示例:
#include <iostream>
using namespace std;
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
class PaintCost {
public:
int getCost(int area) {
return area * 70;
}
};
class Rectangle: public Shape, public PaintCost {
public:
int getArea() {
return (width * height);
}
};
int main(void) {
Rectangle Rect;
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
cout << "Total area: " << Rect.getArea() << endl;
cout << "Total paint cost: $" << Rect.getCost(area) << endl;
return 0;
}
当以上代码被编译和执行时,它产生如下结果:
Total area: 35
Total paint cost: $2450