【C++】类的继承

在C++中,类的继承是一种重要的面向对象编程概念,它允许创建一个新类(称为派生类或子类),该类继承了另一个已存在的类(称为基类或父类)的属性和方法。通过继承,派生类可以重用基类的代码,并添加自己的特定功能。

C++中的类继承可以通过以下语法来实现:

class DerivedClass : accessSpecifier BaseClass {
    // 派生类的成员和方法
};

其中:

  • DerivedClass 是派生类的名称;
  • accessSpecifier 可以是 publicprotectedprivate,用于指定派生类对基类成员的访问权限;
  • BaseClass 是基类的名称,表示派生类从哪个类继承。

在类继承中,有以下几个关键概念:

  1. 公有继承(public inheritance):

    • 使用 public 访问权限来继承基类。公有继承意味着基类的公有成员在派生类中仍然是公有的,保护成员在派生类中变为保护的,私有成员在派生类中不可访问。
  2. 保护继承(protected inheritance):

    • 使用 protected 访问权限来继承基类。保护继承意味着基类的公有和保护成员在派生类中都会变为保护的,私有成员在派生类中不可访问。
  3. 私有继承(private inheritance):

    • 使用 private 访问权限来继承基类。私有继承意味着基类的公有和保护成员在派生类中都会变为私有的,私有成员在派生类中不可访问。
  4. 基类和派生类的关系:

    • 派生类继承了基类的属性和方法,并可以添加自己的成员和方法。
    • 派生类可以访问基类的公有和保护成员,但不能访问基类的私有成员。
    • 派生类可以重写(override)基类的虚函数,实现多态性。
  5. 构造函数和析构函数的继承:

    • 派生类可以继承基类的构造函数和析构函数。
    • 在创建派生类对象时,会先调用基类的构造函数,再调用派生类的构造函数。
    • 在销毁派生类对象时,会先调用派生类的析构函数,再调用基类的析构函数。

当我们考虑一个简单的图形类层次结构时,我们可以使用类的继承来展示这个概念。

假设我们有一个基类 Shape,它表示各种形状的图形,然后我们创建两个派生类 RectangleCircle,分别表示矩形和圆形。

下面是一个示例代码:

#include 
using namespace std;

// 基类:图形类
class Shape {
protected:
    string color;

public:
    Shape(string col);
    void setColor(string col);
    void displayColor();
};

Shape::Shape(string col) {
    color = col;
}

void Shape::setColor(string col) {
    color = col;
}

void Shape::displayColor() {
    cout << "Color: " << color << endl;
}

// 派生类:矩形类
class Rectangle : public Shape {
private:
    double length;
    double width;

public:
    Rectangle(double len, double wid, string col);
    double getArea();
    void display();
};

Rectangle::Rectangle(double len, double wid, string col) : Shape(col) {
    length = len;
    width = wid;
}

double Rectangle::getArea() {
    return length * width;
}

void Rectangle::display() {
    cout << "Length: " << length << endl;
    cout << "Width: " << width << endl;
    cout << "Area: " << getArea() << endl;
}

// 派生类:圆形类
class Circle : public Shape {
private:
    double radius;

public:
    Circle(double rad, string col);
    double getArea();
    void display();
};

Circle::Circle(double rad, string col) : Shape(col) {
    radius = rad;
}

double Circle::getArea() {
    return 3.14 * radius * radius;
}

void Circle::display() {
    cout << "Radius: " << radius << endl;
    cout << "Area: " << getArea() << endl;
}

int main() {
    Rectangle rect(5.0, 3.0, "Blue");
    Circle circle(2.5, "Red");

    rect.displayColor();
    rect.display();

    circle.displayColor();
    circle.display();

    return 0;
}

在上述代码中,我们定义了一个基类 Shape,它有一个 color 成员变量和一些操作颜色的方法。然后,我们创建了两个派生类 RectangleCircle,它们分别继承了基类 Shape

Rectangle 类中,我们添加了 lengthwidth 成员变量,并实现了计算面积和显示矩形信息的方法。而在 Circle 类中,我们添加了 radius 成员变量,并实现了计算面积和显示圆形信息的方法。

main 函数中,我们创建了一个矩形对象和一个圆形对象,并调用它们的成员函数来显示颜色和图形信息。

通过这个实例,我们可以看到基类 Shape 的属性和方法被派生类 RectangleCircle 继承,并且派生类可以添加自己的特定属性和方法。

多继承

多继承是指一个派生类可以从多个基类中继承属性和方法的能力。在C++中,可以使用多继承来创建一个派生类,它同时从多个基类中继承。

多继承的语法如下:

class DerivedClass : accessSpecifier BaseClass1, accessSpecifier BaseClass2, ... {
    // 派生类的成员和方法
};

其中:

  • DerivedClass 是派生类的名称;
  • accessSpecifier 可以是 publicprotectedprivate,用于指定派生类对基类成员的访问权限;
  • BaseClass1, BaseClass2, … 是基类的名称,表示派生类从哪些类继承。

多继承中,派生类会继承每个基类的属性和方法。派生类可以访问每个基类的公有成员,但不能访问私有成员。对于保护成员,其访问权限取决于使用的继承方式。

在多继承中,可能出现以下情况:

  1. 基类命名冲突:如果两个或多个基类具有相同的成员名称,派生类在使用该成员时必须明确指定基类的名称来消除歧义。

  2. 虚继承:当一个派生类从多个基类继承,并且这些基类之间存在继承关系时,可以使用虚继承来避免多次复制相同的基类子对象。通过使用虚继承,可以确保在派生类中只有一个共享的基类子对象。

  3. 菱形继承问题:当一个派生类从两个不同的基类继承,并且这两个基类又继承自同一个基类时,就会出现菱形继承问题。这可能导致在派生类中出现二义性,需要使用虚继承或明确指定基类的名称来解决。

为了说明多继承的概念,我们可以考虑一个简单的示例,假设我们有两个基类 PersonEmployee,然后我们创建一个派生类 Manager,它同时从这两个基类中继承。

下面是一个示例代码:

#include 
using namespace std;

// 基类:人类
class Person {
protected:
    string name;

public:
    Person(string n);
    void setName(string n);
    void display();
};

Person::Person(string n) {
    name = n;
}

void Person::setName(string n) {
    name = n;
}

void Person::display() {
    cout << "Name: " << name << endl;
}

// 基类:雇员类
class Employee {
protected:
    int employeeId;

public:
    Employee(int id);
    void setEmployeeId(int id);
    void display();
};

Employee::Employee(int id) {
    employeeId = id;
}

void Employee::setEmployeeId(int id) {
    employeeId = id;
}

void Employee::display() {
    cout << "Employee ID: " << employeeId << endl;
}

// 派生类:经理类
class Manager : public Person, public Employee {
private:
    string department;

public:
    Manager(string n, int id, string dept);
    void setDepartment(string dept);
    void display();
};

Manager::Manager(string n, int id, string dept) : Person(n), Employee(id) {
    department = dept;
}

void Manager::setDepartment(string dept) {
    department = dept;
}

void Manager::display() {
    Person::display();
    Employee::display();
    cout << "Department: " << department << endl;
}

int main() {
    Manager manager("John Doe", 12345, "Sales");
    manager.display();

    return 0;
}

在上述代码中,我们定义了两个基类 PersonEmployee,它们分别表示人和雇员。然后,我们创建了一个派生类 Manager,它同时从这两个基类中继承。

Manager 类中,我们添加了一个 department 成员变量,并实现了设置部门和显示信息的方法。通过使用多继承,Manager 类可以同时继承 PersonEmployee 类的属性和方法。

main 函数中,我们创建了一个 Manager 对象,并调用它的 display 方法来显示经理的信息。通过多继承,Manager 类可以访问 Person 类和 Employee 类的成员函数,从而实现了对人名、员工ID和部门的显示。

你可能感兴趣的:(C/C++,c++)