当前位置: 首页 > article >正文

C++:面向对象编程(封装、继承和多态)

在C++中,面向对象编程(OOP)主要有三大特性:封装、继承和多态。下面将对这三个特性进行详细解释,并给出相应的代码示例。

1. 封装(Encapsulation)

概念

封装是将数据(属性)和操作数据的函数(方法)捆绑在一起,并对外部隐藏对象的内部实现细节,只提供一些公共的接口来与对象进行交互。这样可以提高代码的安全性和可维护性,防止外部代码直接访问和修改对象的内部数据,从而避免意外的数据损坏。

访问控制符

在C++中,使用访问控制符来实现封装,主要有三种访问控制符:

  • public:公共成员,任何外部代码都可以访问。
  • private:私有成员,只能在类的内部访问,外部代码无法直接访问。
  • protected:受保护成员,只能在类的内部和派生类中访问。
代码示例
#include <iostream>
using namespace std;

class Rectangle {
private:
    // 私有成员变量,外部无法直接访问
    int length;
    int width;

public:
    // 构造函数,用于初始化对象
    Rectangle(int l, int w) {
        length = l;
        width = w;
    }

    // 公共方法,用于计算矩形的面积
    int area() {
        return length * width;
    }

    // 公共方法,用于获取矩形的长度
    int getLength() {
        return length;
    }

    // 公共方法,用于设置矩形的长度
    void setLength(int l) {
        if (l > 0) {
            length = l;
        }
    }
};

int main() {
    Rectangle rect(5, 3);
    cout << "Length: " << rect.getLength() << endl;
    cout << "Area: " << rect.area() << endl;

    rect.setLength(7);
    cout << "New Length: " << rect.getLength() << endl;
    cout << "New Area: " << rect.area() << endl;

    return 0;
}

在上述代码中,lengthwidth 是私有成员变量,外部代码无法直接访问。通过公共的方法 getLength()setLength() 来间接访问和修改 length 的值,从而实现了数据的封装。

2. 继承(Inheritance)

概念

继承是指一个类(派生类,也称为子类)可以继承另一个类(基类,也称为父类)的属性和方法。通过继承,可以实现代码的复用,避免重复编写相同的代码。同时,派生类还可以添加自己的属性和方法,或者重写基类的方法,以满足不同的需求。

继承方式

在C++中,继承方式有三种:

  • public:公共继承,基类的公共成员和受保护成员在派生类中保持原有的访问权限。
  • private:私有继承,基类的公共成员和受保护成员在派生类中变为私有成员。
  • protected:受保护继承,基类的公共成员和受保护成员在派生类中变为受保护成员。
代码示例
#include <iostream>
using namespace std;

// 基类
class Shape {
protected:
    int width;
    int height;

public:
    Shape(int w, int h) {
        width = w;
        height = h;
    }

    // 虚函数,用于实现多态
    virtual int area() {
        cout << "Parent class area: ";
        return 0;
    }
};

// 派生类,继承自 Shape 类
class Rectangle : public Shape {
public:
    Rectangle(int w, int h) : Shape(w, h) {}

    // 重写基类的 area 方法
    int area() {
        cout << "Rectangle class area: ";
        return width * height;
    }
};

// 派生类,继承自 Shape 类
class Triangle : public Shape {
public:
    Triangle(int w, int h) : Shape(w, h) {}

    // 重写基类的 area 方法
    int area() {
        cout << "Triangle class area: ";
        return (width * height) / 2;
    }
};

int main() {
    Shape *shape;
    Rectangle rect(5, 3);
    Triangle tri(5, 3);

    // 指向 Rectangle 对象
    shape = &rect;
    cout << shape->area() << endl;

    // 指向 Triangle 对象
    shape = &tri;
    cout << shape->area() << endl;

    return 0;
}

在上述代码中,RectangleTriangle 类都继承自 Shape 类,它们继承了 Shape 类的 widthheight 属性以及 area() 方法。同时,RectangleTriangle 类分别重写了 area() 方法,以实现各自的面积计算逻辑。

3. 多态(Polymorphism)

概念

多态是指同一个函数调用可以根据对象的实际类型执行不同的实现。在C++中,多态主要通过虚函数和函数重载来实现。虚函数允许在基类中声明一个函数为虚函数,派生类可以重写这个虚函数,当通过基类指针或引用调用该虚函数时,会根据对象的实际类型调用相应的派生类的实现。

虚函数和纯虚函数
  • 虚函数:在基类中使用 virtual 关键字声明的函数,派生类可以重写该函数。
  • 纯虚函数:在基类中使用 virtual 关键字声明,并且赋值为 0 的函数,纯虚函数没有具体的实现,包含纯虚函数的类称为抽象类,抽象类不能实例化对象。
代码示例
#include <iostream>
using namespace std;

// 抽象类
class Shape {
public:
    // 纯虚函数
    virtual int area() = 0;
};

// 派生类,继承自 Shape 类
class Rectangle : public Shape {
private:
    int width;
    int height;

public:
    Rectangle(int w, int h) {
        width = w;
        height = h;
    }

    // 重写基类的纯虚函数
    int area() {
        return width * height;
    }
};

// 派生类,继承自 Shape 类
class Triangle : public Shape {
private:
    int base;
    int height;

public:
    Triangle(int b, int h) {
        base = b;
        height = h;
    }

    // 重写基类的纯虚函数
    int area() {
        return (base * height) / 2;
    }
};

int main() {
    Shape *shape;
    Rectangle rect(5, 3);
    Triangle tri(5, 3);

    // 指向 Rectangle 对象
    shape = &rect;
    cout << "Rectangle area: " << shape->area() << endl;

    // 指向 Triangle 对象
    shape = &tri;
    cout << "Triangle area: " << shape->area() << endl;

    return 0;
}

在上述代码中,Shape 类是一个抽象类,包含一个纯虚函数 area()RectangleTriangle 类继承自 Shape 类,并分别重写了 area() 方法。通过基类指针 shape 可以根据实际指向的对象类型调用相应的 area() 方法,实现了多态。

综上所述,封装、继承和多态是C++面向对象编程的核心特性,它们相互配合,使得代码更加模块化、可复用和易于维护。


http://www.kler.cn/a/570977.html

相关文章:

  • 深入理解 `udev`:Linux 设备管理的核心机制
  • Leetcode 49: 字母异位词分组
  • Java自动拆箱装箱/实例化顺序/缓存使用/原理/实例
  • 基于SpringBoot的校园二手交易平台(源码+论文+部署教程)
  • 通用查询类接口数据更新的另类实现
  • python爬虫报错信息解决方法
  • 02原理篇(D2_SpringBoot 自动装配原理)
  • 设计模式:记录所有设计模式方便后续复习
  • 3.1、密码学基础
  • PGlite:浏览器中运行的PostgreSQL
  • 【大模型】大模型分类
  • Teacher Forcing
  • 【Linux探索学习】第三十弹——线程互斥与同步(上):深入理解线程保证安全的机制
  • k8s架构及服务详解
  • Unity 对象池技术
  • Python 网络爬虫的应用
  • java后端开发day26--常用API(一)
  • Arduino引脚说明
  • DDK:Distilling Domain Knowledge for Efficient Large Language Models
  • AI大模型与区块链技术的结合