C++学习笔记(十八)——类之继承

一、 继承

作用:
继承(Inheritance) 是面向对象编程(OOP)的核心特性之一,允许一个类(子类)从另一个类(基类)派生,并继承基类的属性和行为

继承的主要目的代码复用,同时支持扩展和修改已有功能,提高程序的可维护性。

特点

  • 子类会自动继承基类的 publicprotected 成员(不包括 private 成员)
  • 子类可以增加新的成员或重写(覆盖)基类的方法
  • 支持单继承和多继承(C++ 允许一个类继承多个基类)。
  • 继承方式决定了基类成员的访问权限

二、 继承的基本语法

基本语法:

class 子类名 : 继承方式 基类名 {
    // 子类成员
};

继承方式对成员访问的影响:

继承方式 基类 public 变成 基类 protected 变成 基类 private 变成
public推荐 public protected 无法访问
protected protected protected 无法访问
private private private 无法访问

示例 ——基本继承:

#include 
using namespace std;

// 基类(父类)
class Animal {
public:
    void eat() 
    {
        cout << "动物正在进食" << endl;
    }
};

// 子类(派生类)
class Dog : public Animal {
public:
    void bark() 
    {
        cout << "狗在叫:汪汪!" << endl;
    }
};

int main() {
    Dog d;
    d.eat();  // 继承自 Animal
    d.bark(); // Dog 类自己的方法

    system("pause");
    return 0;
}

注意:

  • Dog 继承 Animal,可以直接调用 eat() 方法。
  • bark() 方法是 Dog 自己的扩展功能。

三、 继承中的构造函数与析构函数

  • 子类不会继承基类的构造函数,但可以调用基类的构造函数
  • 构造对象时,先调用基类构造函数,再调用子类构造函数
  • 析构对象时,先调用子类析构函数,再调用基类析构函数析构顺序与构造相反)。

示例——继承中的构造与析构:

#include 
using namespace std;

class Animal {
public:
    Animal() 
    { 
        cout << "Animal 构造函数" << endl; 
    }
    ~Animal() 
    { 
        cout << "Animal 析构函数" << endl; 
    }
};

class Dog : public Animal {
public:
    Dog() 
    { 
        cout << "Dog 构造函数" << endl; 
    }
    ~Dog() 
    { 
        cout << "Dog 析构函数" << endl; 
    }
};

void test01()
{
    Dog d;
}

int main() {
    test01();

    system("pause");
    return 0;
}

注意:

  • 构造顺序: 先调用 Animal(基类),再调用 Dog(子类)。
  • 析构顺序: 先销毁 Dog,再销毁 Animal

四、特殊用法

(1) 子类调用基类构造函数

作用:
子类可以显式调用基类的构造函数初始化基类成员

示例——子类调用基类构造函数:

#include 
using namespace std;

class Animal {
protected:
    string name;
public:
    Animal(string n) : name(n) 
    { 
        cout << "Animal 构造: " << name << endl; 
    }
};

class Dog : public Animal {
public:
    Dog(string n) : Animal(n) 
    { 
        cout << "Dog 构造: " << name << endl; 
    }
};

int main() {
    Dog d("旺财");

    system("pause");
    return 0;
}

注意:

  • Dog 的构造函数调用了 Animal 的构造函数,并传递 name

(2) 方法重写(Override)

作用:
子类可以重新实现基类的方法,但必须保证函数签名一致

示例——重写 speak() 方法:

#include 
using namespace std;

class Animal {
public:
    void speak() 
    {
        cout << "动物在发出声音" << endl;
    }
};

class Dog : public Animal {
public:
    void speak() // 重写基类方法
    {
        cout << "狗在叫:汪汪!" << endl;
    }
};

int main() {
    Dog d;
    d.speak();  // 调用 Dog 的 speak

    system("pause");
    return 0;
}

注意:

  • Dog::speak() 覆盖 Animal::speak(),子类方法优先执行

(3)protected 继承

作用:

  • protected 继承后,基类 public 成员变成 protected,外部不能访问。
  • 适用于希望子类继承基类功能,但不让外部直接使用基类成员的情况

示例——protected 继承:

#include 
using namespace std;

class A {
public:
    void show() 
    { 
        cout << "A::show()" << endl; 
    }
};

class B : protected A {
public:
    void callShow() // 只能在子类内部访问show(); 
    { 
        show(); 
    }
};

int main() {
    B obj;
    // obj.show();      // 错误:基类的 `public` 变成 `protected`
    obj.callShow();     // 正确

    system("pause");
    return 0;
}

分析

  • show()B 中变成 protected,不能直接用 obj.show()

(4) 多继承

C++ 允许一个类继承多个基类,但可能导致命名冲突

示例——多继承:

#include 
using namespace std;

class A {
public:
    void show() 
    { 
        cout << "A::show()" << endl; 
    }
};

class B {
public:
    void show() 
    { 
        cout << "B::show()" << endl; 
    }
};

class C : public A, public B {};

int main() {
    C obj;
    // obj.show();  // 错误 二义性错误
    obj.A::show();  // 正确 解决冲突

    system("pause");
    return 0;
}

注意:

  • 多继承可能导致函数冲突,需要指定 obj.A::show() 解决。

你可能感兴趣的:(C++基础学习,c++,学习,笔记)