c++学习:继承

目录

特点

基本用法

实例

基类:Animal

派生类:Lion

派生类:Elephant

派生类:Bird

使用这些类

权限对继承的影响

示例

基类构造函数

示例


继承是面向对象编程(OOP)中的一个核心概念,特别是在C++中。它允许一个类(称为派生类或子 类)继承另一个类(称为基类或父类)的属性和方法。继承的主要目的是实现代码重用,以及建立一种 类型之间的层次关系。

特点

  • 代码重用:子类继承了父类的属性和方法,减少了代码的重复编写。
  • 扩展性:子类可以扩展父类的功能,添加新的属性和方法,或者重写(覆盖)现有的方法。
  • 多态性:通过继承和虚函数,C++支持多态,允许在运行时决定调用哪个函数。

基本用法

继承可以是公有(public)、保护(protected)或私有(private)的,这决定了基类成员在 派生类中的访问权限

#include <iostream>
using namespace std;
//基类,父类
class Vehicle{ //交通工具,车,抽象的概念
public:
    string type;
    string contry;
    string color;
    double price;
    int numOfWheel;
    void run(){
        cout << "车跑起来了" << endl;
    }
    void stop();
};
//派生类,子类
class Bickle : public Vehicle{

};
//派生类,子类
class Roadster : public Vehicle{ //跑车,也是抽象,比父类感觉上范围缩小了点
public:
    int stateOfTop;
    void openTopped();
    void pdrifting();
};
int main()
{
    Roadster ftype;
    ftype.type = "捷豹Ftype";
    ftype.run();
    Bickle bike;
    bike.type = "死飞";
    bike.run();
    return 0;
}

Vehicle 类公有地继承自 Vehicle 类,这意味着所有 Vehicle 类的公有成员在 Vehicle 类中也是公有的

实例

我们有一个基类 Animal ,它定义了所有动物共有的特性和行为。然 后,我们可以创建几个派生类,如 Lion 、 Elephant 和 Bird ,这些类继承自 Animal 类,并添加或 修改特定于它们自己的特性和行为

基类:Animal

#include <iostream>
#include <string>
class Animal {
protected:
    std::string name;
    int age;
public:
    Animal(std::string n, int a) : name(n), age(a) {}
    virtual void makeSound() {
        std::cout << name << " makes a sound." << std::endl;
    }
    virtual void display() {
        std::cout << "Animal: " << name << ", Age: " << age << std::endl;
    }
};

派生类:Lion

class Lion : public Animal {
public:
    Lion(std::string n, int a) : Animal(n, a) {}
    void makeSound() override {
        std::cout << name << " roars." << std::endl;
    }
    void display() override {
        std::cout << "Lion: " << name << ", Age: " << age << std::endl;
    }
};

派生类:Elephant

class Elephant : public Animal {
public:
    Elephant(std::string n, int a) : Animal(n, a) {}
    void makeSound() override {
        std::cout << name << " trumpets." << std::endl;
    }
    void display() override {
        std::cout << "Elephant: " << name << ", Age: " << age << std::endl;
    }
};

派生类:Bird

class Bird : public Animal {
public:
    Bird(std::string n, int a) : Animal(n, a) {}
    void makeSound() override {
        std::cout << name << " sings." << std::endl;
    }
    void display() override {
        std::cout << "Bird: " << name << ", Age: " << age << std::endl;
    }
};

使用这些类

int main() {
    Lion lion("Leo", 5);
    Elephant elephant("Ella", 10);
    Bird bird("Bella", 2);
    lion.display();
    lion.makeSound();
    elephant.display();
    elephant.makeSound();
    bird.display();
    bird.makeSound();
    return 0;
}
  • Animal 是基类,定义了所有动物共有的属性(如 name 和 age )和方法(如 makeSound 和 display )。
  • Lion 、 Elephant 和 Bird 是派生类,它们继承了 Animal 的特性,并根据自身的特性重写了 makeSound 和 display 方法。
  • 在 main 函数中,创建了各种动物的实例,并展示了它们的行为。

权限对继承的影响

  • public 继承:基类的 public 成员在派生类中仍然是 public 的, protected 成员仍然是 protected 的。基类的 private 成员在派生类中不可访问。
  • protected 继承:基类的 public 和 protected 成员在派生类中都变成 protected 的。基类 的 private 成员在派生类中不可访问。
  • private 继承:基类的 public 和 protected 成员在派生类中都变成 private 的。基类的 private 成员在派生类中不可访问。

示例

#include <iostream>
using namespace std;
//基类,父类
class Vehicle{ //交通工具,车,抽象的概念
public:
    string type;
    string contry;
    string color;
    double price;
    int numOfWheel;
protected:
    int protectedData;
private:
    int privateData;
public:
    void run(){
        cout << "车跑起来了" << endl;
    }
    void stop();
};
//私有继承测试
class TestClass : private Vehicle{
public:
    void tsetFunc(){
        price = 10; //基类的公有数据被私有继承后,在派生类中权限编程私有,只限在类内部使用
    }
};
//公有继承测试
class Truck : protected Vehicle{
public:
    void testFunc(){
        type = "数据测试"; //编程了公有权限
        protectedData = 10; //保持公有权限
        privateData = 10; //报错了,基类的私有成员,不管哪种方式的继承都是不可访问的。
    }
};
//公有继承,基类的公有权限和保护权限不变,私有成员不能访问
class Bickle : public Vehicle{
public:
    void testFunc(){
        protectedData = 10;
    }
};
//派生类,子类
class Roadster : public Vehicle{ //跑车,也是抽象,比父类感觉上范围缩小了点
public:
    int stateOfTop;
    void openTopped();
    void pdrifting();
};
int main()
{
    TestClass test;
    test.price = 3.3; //报错了,基类的公有成员被私有继承后,降为私有权限
    Truck t;
    t.type = "测试"; //报错了,基类的公有成员被保护继承后,降为保护权限
    t.protectedData = 10; //从报错信息看出,保护继承造成基类的保护成员还是保持保护权限
    Roadster ftype;
    ftype.type = "捷豹Ftype";
    ftype.run();
    Bickle bike;
    bike.type = "死飞";
    bike.run();
    return 0;
}

基类构造函数

派生类可以通过其构造函数的初始化列表来调用基类的构造函数。这是在构造派生类对象时初 始化基类部分的标准做法

当创建派生类的对象时,基类的构造函数总是在派生类的构造函数之前被调用。如果没有明确指定,将 调用基类的默认构造函数。如果基类没有默认构造函数,或者你需要调用一个特定的基类构造函数,就 需要在派生类构造函数的初始化列表中明确指定

示例

假设我们有一个基类 Base 和一个派生自 Base 的类 Derived

class Base {
public:
    int data;
    Base(int x) {
        std::cout << "Base constructor with x = " << x << std::endl;
    }
};
class Derived : public Base {
public:
    double ydata;
    Derived(int x, double y) : Base(x) { // 调用 Base 类的构造函数
        std::cout << "Derived constructor with y = " << y << std::endl;
    }
};
int main() {
    Derived obj(10, 3.14); // 首先调用 Base(10),然后调用 Derived 的构造函数
    return 0;
}
  • Base 类有一个接受一个整数参数的构造函数。
  • Derived 类继承自 Base ,它的构造函数接受一个整数和一个双精度浮点数。在其初始化列表中, 它调用 Base 类的构造函数,并传递整数参数。
  • 当 Derived 类的对象被创建时,首先调用 Base 类的构造函数,然后调用 Derived 类的构造函 数。
相关推荐
oneouto5 分钟前
selenium学习笔记(二)
笔记·学习·selenium
sealaugh329 分钟前
aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发
笔记·学习·aws
炭烤玛卡巴卡36 分钟前
学习postman工具使用
学习·测试工具·postman
thesky1234561 小时前
活着就好20241224
学习·算法
蜗牛hb1 小时前
VMware Workstation虚拟机网络模式
开发语言·学习·php
汤姆和杰瑞在瑞士吃糯米粑粑1 小时前
【C++学习篇】AVL树
开发语言·c++·学习
虾球xz2 小时前
游戏引擎学习第58天
学习·游戏引擎
奶香臭豆腐2 小时前
C++ —— 模板类具体化
开发语言·c++·学习
波音彬要多做3 小时前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
m0_748256784 小时前
WebGIS实战开源项目:智慧机场三维可视化(学习笔记)
笔记·学习·开源