【C++】多态、继承和封装详解与示例

引言

在C++中,多态、继承和封装是面向对象编程(OOP)的三大核心特性。它们共同支持了代码的复用、扩展和维护。本文将深入解析这三个特性的原理,并通过示例展示它们在C++中的应用。

封装(Encapsulation)

原理

封装是一种将数据和操作数据的函数绑定在一起,形成一个不可分割的整体(即类)的技术。它隐藏了对象的内部实现细节,仅对外公开接口(public成员函数),从而提高了数据的安全性,并简化了对象的使用。

示例

cpp 复制代码
#include <iostream>
using namespace std;

class Account {
private:
    double balance;

public:
    Account(double initialBalance) : balance(initialBalance) {}

    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }

    double getBalance() const {
        return balance;
    }
};

int main() {
    Account myAccount(100.0);
    myAccount.deposit(50.0);
    cout << "Balance: " << myAccount.getBalance() << endl;
    return 0;
}

继承(Inheritance)

原理

继承允许我们定义一个基于现有类的类(称为子类或派生类),从而复用和扩展现有类的功能。子类可以继承父类的属性和方法,也可以添加新的属性和方法或重写(Override)继承的方法。

示例

cpp 复制代码
#include <iostream>
using namespace std;

class Vehicle {
protected:
    string brand;

public:
    Vehicle(string b) : brand(b) {}

    virtual void display() const {
        cout << "Brand: " << brand << endl;
    }
};

class Car : public Vehicle {
private:
    int seats;

public:
    Car(string b, int s) : Vehicle(b), seats(s) {}

    void display() const override {
        Vehicle::display(); // 调用父类方法
        cout << "Seats: " << seats << endl;
    }
};

int main() {
    Car myCar("Toyota", 5);
    myCar.display();
    return 0;
}

多态(Polymorphism)

原理

多态允许不同类的对象对同一消息作出响应。在C++中,多态通常通过虚函数实现。当通过基类指针或引用来调用虚函数时,会根据指针或引用实际指向的对象的类型来调用相应的函数版本,这就是运行时多态(也称为动态多态)。

示例

cpp 复制代码
#include <iostream>
#include <vector>
#include <memory>
using namespace std;

class Shape {
public:
    virtual void draw() const = 0; // 纯虚函数,强制子类实现
    virtual &#126;Shape() {} // 虚析构函数
};

class Circle : public Shape {
public:
    void draw() const override {
        cout << "Drawing Circle" << endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() const override {
        cout << "Drawing Rectangle" << endl;
    }
};

int main() {
    vector<shared_ptr<Shape>> shapes;
    shapes.push_back(make_shared<Circle>());
    shapes.push_back(make_shared<Rectangle>());

    for (const auto& shape : shapes) {
        shape->draw(); // 运行时多态
    }

    return 0;
}

综合示例

下面将提供一个基于C++的综合示例代码,该代码结合了多态、继承和封装的概念,以创建一个简单的绘图系统。在这个系统中,我们将定义几个图形类(如圆形和矩形),它们都继承自一个共同的基类Shape,并实现了自己的draw方法。最后,我们将通过一个主函数来展示如何使用这些图形类,并利用多态性统一处理不同的图形对象。

代码

cpp 复制代码
#include <iostream>
#include <vector>
#include <memory>

// 基类Shape,包含纯虚函数draw()
class Shape {
public:
    virtual void draw() const = 0; // 纯虚函数,强制派生类实现
    virtual &#126;Shape() {} // 虚析构函数,确保通过基类指针删除派生类对象时调用正确的析构函数
};

// 圆形类,继承自Shape
class Circle : public Shape {
private:
    double radius;

public:
    Circle(double r) : radius(r) {}

    void draw() const override {
        std::cout << "Drawing Circle with radius: " << radius << std::endl;
    }
};

// 矩形类,继承自Shape
class Rectangle : public Shape {
private:
    double width, height;

public:
    Rectangle(double w, double h) : width(w), height(h) {}

    void draw() const override {
        std::cout << "Drawing Rectangle with width: " << width << " and height: " << height << std::endl;
    }
};

// 主函数,展示如何使用多态和继承
int main() {
    // 使用智能指针存储Shape类型的对象,这些对象可以是Circle或Rectangle的实例
    std::vector<std::shared_ptr<Shape>> shapes;
    shapes.push_back(std::make_shared<Circle>(5.0));
    shapes.push_back(std::make_shared<Rectangle>(3.0, 4.0));

    // 通过基类指针调用draw方法,展示多态性
    for (const auto& shape : shapes) {
        shape->draw();
    }

    return 0;
}

代码详解

代码中:
基类Shape:定义了一个纯虚函数draw(),这要求所有从Shape派生的类都必须实现draw()方法。同时,提供了一个虚析构函数,这是处理通过基类指针删除派生类对象时的一个好习惯,可以确保正确的析构函数被调用。

派生类Circle和Rectangle:这两个类都继承自Shape类,并实现了自己的draw()方法。在Circle类中,draw()方法输出圆的半径;在Rectangle类中,draw()方法输出矩形的宽度和高度。

主函数main:首先,创建了一个std::vector<std::shared_ptr>类型的容器,用于存储指向Shape对象的智能指针。然后,向该容器中添加了两个对象:一个Circle对象和一个Rectangle对象。由于这两个类都继承自Shape,因此它们都可以被存储在同一容器中。最后,通过遍历容器并使用基类指针调用draw()方法,展示了多态性。尽管我们使用的是Shape类型的指针,但实际上调用的是指向对象的实际类型(Circle或Rectangle)的draw()方法。

这个示例展示了多态、继承和封装在C++中的实际应用,以及它们如何共同工作以创建灵活且可扩展的面向对象程序。

相关推荐
远望清一色5 分钟前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
confiself14 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
凌云行者24 分钟前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
XiaoLeisj26 分钟前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
凌云行者27 分钟前
OpenGL入门006——着色器在纹理混合中的应用
c++·cmake·opengl
杜杜的man29 分钟前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*30 分钟前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
半桶水专家31 分钟前
go语言中package详解
开发语言·golang·xcode
llllinuuu31 分钟前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s32 分钟前
Golang--协程和管道
开发语言·后端·golang