C&C++快速入门

22、继承

1、课程目标

  • 理解继承的概念和作用
  • 掌握访问控制在继承中的作用
  • 理解构造和析构的调用顺序
  • 了解多重继承

2、名词解释

术语 说明
继承 子类获取父类的属性和方法
基类/父类 被继承的类
派生类/子类 继承其他类的类
public继承 保持父类访问级别
protected继承 public降级为protected
private继承 全部降级为private

3、代码实现

1. 基础继承

#include <iostream>
using namespace std;

class Animal {
protected:
    string m_name;
    int m_age;
    
public:
    Animal(const string& name, int age) 
        : m_name(name), m_age(age) {
        cout << "Animal构造: " << m_name << endl;
    }
    
    virtual ~Animal() {
        cout << "Animal析构: " << m_name << endl;
    }
    
    void PrintInfo() {
        cout << "Name: " << m_name << ", Age: " << m_age << endl;
    }
    
    virtual void Speak() {
        cout << m_name << " makes a sound" << endl;
    }
};

class Dog : public Animal {
private:
    string m_breed;
    
public:
    Dog(const string& name, int age, const string& breed)
        : Animal(name, age), m_breed(breed) {
        cout << "Dog构造: " << m_breed << endl;
    }
    
    ~Dog() {
        cout << "Dog析构: " << m_breed << endl;
    }
    
    void Speak() override {
        cout << m_name << " barks: Woof!" << endl;
    }
    
    void Fetch() {
        cout << m_name << " is fetching" << endl;
    }
};

int main() {
    cout << "=== 继承 ===" << endl << endl;
    
    Dog dog("Buddy", 3, "Golden Retriever");
    cout << endl;
    
    dog.PrintInfo();  // 继承的方法
    dog.Speak();      // 重写的方法
    dog.Fetch();      // 自己的方法
    
    cout << endl;
    return 0;
}

2. 访问控制

#include <iostream>
using namespace std;

class Base {
public:
    int pub = 1;
protected:
    int prot = 2;
private:
    int priv = 3;
};

class PublicDerived : public Base {
public:
    void Access() {
        cout << pub << endl;   // OK
        cout << prot << endl;  // OK
        // cout << priv;       // 错误: 无法访问
    }
};

class ProtectedDerived : protected Base {
public:
    void Access() {
        cout << pub << endl;   // OK, 变为protected
        cout << prot << endl;  // OK
    }
};

int main() {
    cout << "=== 访问控制 ===" << endl << endl;
    
    PublicDerived pd;
    pd.pub = 10;    // OK
    // pd.prot = 20; // 错误: protected在外部无法访问
    
    ProtectedDerived protd;
    // protd.pub = 10; // 错误: 变为protected了
    
    cout << "访问控制测试完成" << endl;
    
    return 0;
}

3. 多重继承

#include <iostream>
using namespace std;

class Flyable {
public:
    virtual void Fly() {
        cout << "Flying" << endl;
    }
};

class Swimmable {
public:
    virtual void Swim() {
        cout << "Swimming" << endl;
    }
};

class Duck : public Flyable, public Swimmable {
public:
    void Fly() override {
        cout << "Duck flying" << endl;
    }
    
    void Swim() override {
        cout << "Duck swimming" << endl;
    }
};

int main() {
    cout << "=== 多重继承 ===" << endl << endl;
    
    Duck duck;
    duck.Fly();
    duck.Swim();
    
    // 可以通过不同的基类指针操作
    Flyable* flyable = &duck;
    Swimmable* swimmable = &duck;
    
    cout << "\n通过基类指针:" << endl;
    flyable->Fly();
    swimmable->Swim();
    
    return 0;
}

4、课后作业

4.1、作业1:实现图形类层次

实现Shape基类和Circle、Rectangle子类。

4.2、作业2:模拟插件系统

使用继承实现可扩展的插件系统。