第十二章 类和对象——封装

news2024/11/28 23:32:20

C++面向对象的三大特性为:封装、继承、多态

C++认为万事万物都皆为对象,对象上有其属性和行为

例如:

人可以作为对象,属性有姓名、年龄、身高、体重...,行为有走、跑、跳、吃饭、唱歌...

车也可以作为对象,属性有轮胎、方向盘、车灯...,行为有载人、放音乐、放空调...

具有相同性质的对象,我们可以抽象称为类,人属于人类,车属于车类

一、封装的意义

封装是C++面向对象三大特性之一

封装的意义:

  • 将属性和行为作为一个整体,表现生活中的事物

  • 将属性和行为加以权限控制

封装意义一:

在设计类的时候,属性和行为写在一起,表现事物

语法: class 类名{ 访问权限: 属性 / 行为 };

示例1:设计一个圆类,求圆的周长

示例代码:

 //圆周率
 const double PI = 3.14;
 ​
 //1、封装的意义
 //将属性和行为作为一个整体,用来表现生活中的事物
 ​
 //封装一个圆类,求圆的周长
 //class代表设计一个类,后面跟着的是类名
 class Circle
 {
 public:  //访问权限  公共的权限
 ​
     //属性
     int m_r;//半径
 ​
     //行为
     //获取到圆的周长
     double calculateZC()
     {
         //2 * pi  * r
         //获取圆的周长
         return  2 * PI * m_r;
     }
 };
 ​
 int main() {
 ​
     //通过圆类,创建圆的对象
     // c1就是一个具体的圆
     Circle c1;
     c1.m_r = 10; //给圆对象的半径 进行赋值操作
 ​
     //2 * pi * 10 = = 62.8
     cout << "圆的周长为: " << c1.calculateZC() << endl;
 ​
     system("pause");
 ​
     return 0;
 }

示例2:设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号

示例2代码:  ​

 //学生类
 class Student {
 public:
     void setName(string name) {
         m_name = name;
     }
     void setID(int id) {
         m_id = id;
     }
 ​
     void showStudent() {
         cout << "name:" << m_name << " ID:" << m_id << endl;
     }
 public:
     string m_name;
     int m_id;
 };
 ​
 int main() {
 ​
     Student stu;
     stu.setName("德玛西亚");
     stu.setID(250);
     stu.showStudent();
 ​
     system("pause");
 ​
     return 0;
 }

封装意义二:

类在设计时,可以把属性和行为放在不同的权限下,加以控制

访问权限有三种:

  1. public 公共权限

  2. protected 保护权限

  3. private 私有权限

示例:

 //三种权限
 //公共权限  public     类内可以访问  类外可以访问
 //保护权限  protected  类内可以访问  类外不可以访问
 //私有权限  private    类内可以访问  类外不可以访问
 ​
 class Person
 {
     //姓名  公共权限
 public:
     string m_Name;
 ​
     //汽车  保护权限
 protected:
     string m_Car;
 ​
     //银行卡密码  私有权限
 private:
     int m_Password;
 ​
 public:
     void func()
     {
         m_Name = "张三";
         m_Car = "拖拉机";
         m_Password = 123456;
     }
 };
 ​
 int main() {
 ​
     Person p;
     p.m_Name = "李四";
     //p.m_Car = "奔驰";  //保护权限类外访问不到
     //p.m_Password = 123; //私有权限类外访问不到
 ​
     system("pause");
 ​
     return 0;
 }

二、struct和class区别

在C++中 struct和class唯一的区别就在于 默认的访问权限不同

区别:

  • struct 默认权限为公共

  • class 默认权限为私有

 class C1
 {
     int  m_A; //默认是私有权限
 };
 ​
 struct C2
 {
     int m_A;  //默认是公共权限
 };
 ​
 int main() {
 ​
     C1 c1;
     c1.m_A = 10; //错误,访问权限是私有
 ​
     C2 c2;
     c2.m_A = 10; //正确,访问权限是公共
 ​
     system("pause");
 ​
     return 0;
 }

三、成员属性设置为私有

优点1:将所有成员属性设置为私有,可以自己控制读写权限

优点2:对于写权限,我们可以检测数据的有效性

示例:

 class Person {
 public:
 ​
     //姓名设置可读可写
     void setName(string name) {
         m_Name = name;
     }
     string getName()
     {
         return m_Name;
     }
 ​
 ​
     //获取年龄 
     int getAge() {
         return m_Age;
     }
     //设置年龄
     void setAge(int age) {
         if (age < 0 || age > 150) {
             cout << "你个老妖精!" << endl;
             return;
         }
         m_Age = age;
     }
 ​
     //情人设置为只写
     void setLover(string lover) {
         m_Lover = lover;
     }
 ​
 private:
     string m_Name; //可读可写  姓名
     
     int m_Age; //只读  年龄
 ​
     string m_Lover; //只写  情人
 };
 ​
 ​
 int main() {
 ​
     Person p;
     //姓名设置
     p.setName("张三");
     cout << "姓名: " << p.getName() << endl;
 ​
     //年龄设置
     p.setAge(50);
     cout << "年龄: " << p.getAge() << endl;
 ​
     //情人设置
     p.setLover("苍井");
     //cout << "情人: " << p.m_Lover << endl;  //只写属性,不可以读取
 ​
     system("pause");
 ​
     return 0;
 }

练习案例1:设计立方体类

设计立方体类(Cube)

求出立方体的面积和体积

分别用全局函数和成员函数判断两个立方体是否相等。

                                        

#include<iostream>
using namespace std;

class Cube
{
    private:
        int m_l;
        int m_w;
        int m_h;
    public:
        // setter and getter
        void setL(int l)
        {
            m_l = l;
        }
        int getL()
        {
            return m_l;
        }
        void setW(int w)
        {
            m_w = w;
        }
        int getW()
        {
            return m_w;
        }
        void setH(int h)
        {
            m_h = h;
        }
        int getH()
        {
            return m_h;
        }

        // 获取周长
        int getPerimeter()
        {
            return 2 * m_l * m_w + 2 * m_l * m_h + 2 * m_w * m_h;
        }

        // 获取体积
        int getVolume()
        {
            return m_l * m_w * m_h;
        }

        // 判断相等
        bool isSame(Cube &c)
        {
            return m_l == c.getL() && m_w == c.getW() && m_h == c.getH();
        }



};
bool isSame(Cube &c1, Cube &c2)
{
    return c1.getL() == c2.getL() && c1.getW() == c2.getW() && c1.getH() == c2.getH();
}
int main()
{
    
    return 0;
}

练习案例2:点和圆的关系

设计一个圆形类(Circle),和一个点类(Point),计算点和圆的关系。

                ​​​​​​​        ​​​​​​​        ​​​​​​​

法一:在一个文件中编写类的代码

#include<iostream>
using namespace std;

class Pointer
{
    private:
        int m_x;
        int m_y;
    public:
        void setX(int x)
        {
            m_x = x;
        }
        int getX()
        {
            return m_x;
        }
        void setY(int y)
        {
            m_y = y;
        }
        int getY()
        {
            return m_y;
        }
};

class Circle
{
    private:
        int m_r;
        Pointer m_center;
    public:
        void setR(int r)
        {
            m_r = r;
        }
        int getR()
        {
            return m_r;
        }
        void setCenter(Pointer center)
        {
            m_center = center;
        }
        Pointer getCenter()
        {
            return m_center;
        }
};

void position(Circle circle, Pointer p)
{
    int distance = 
        (p.getX() - circle.getCenter().getX()) * (p.getX() - circle.getCenter().getX()) + 
        (p.getY() - circle.getCenter().getY()) * (p.getY() - circle.getCenter().getY());
    int r = circle.getR() * circle.getR();

    if(distance <= r)
    {
        cout << "点在圆上!" << endl;
    }
    else
    {
        cout << "点在圆外!" << endl;
    }
}

int main()
{
    Pointer center;
    center.setX(10);
    center.setY(0);

    Circle circle;
    circle.setR(10);
    circle.setCenter(center);

    Pointer p;
    p.setX(10);
    p.setY(11);

    position(circle, p);

    return 0;
}

法二:分文件编写类的代码

circle.h

#pragma once
#include<iostream>
#include"pointer.h"
using namespace std;

class Circle
{
    private:
        int m_r;
        Pointer m_center;
    public:
        void setR(int r);
        int getR();
        void setCenter(Pointer center);
        Pointer getCenter();
};

pointer.h

#pragma once
#include<iostream>
using namespace std;
class Pointer
{
    private:
        int m_x;
        int m_y;
    public:
        void setX(int x);
        int getX();
        void setY(int y);
        int getY();
};

circle.cpp

#include "pointer.h"
#include "circle.h"

void Circle::setR(int r)
{
    m_r = r;
}
int Circle::getR()
{
    return m_r;
}
void Circle::setCenter(Pointer center)
{
    m_center = center;
}
Pointer Circle::getCenter()
{
    return m_center;
}

pointer.cpp

#include "pointer.h"

void Pointer::setX(int x)
{
    m_x = x;
}
int Pointer::getX()
{
    return m_x;
}
void Pointer::setY(int y)
{
    m_y = y;
}
int Pointer::getY()
{
    return m_y;
}

测试程序classTest.cpp

#include "circle.h"
void position(Circle circle, Pointer p)
{
    int distance = 
        (p.getX() - circle.getCenter().getX()) * (p.getX() - circle.getCenter().getX()) + 
        (p.getY() - circle.getCenter().getY()) * (p.getY() - circle.getCenter().getY());
    int r = circle.getR() * circle.getR();

    if(distance <= r)
    {
        cout << "点在圆上!" << endl;
    }
    else
    {
        cout << "点在圆外!" << endl;
    }
}

int main()
{
    Pointer center;
    center.setX(10);
    center.setY(0);

    Circle circle;
    circle.setR(10);
    circle.setCenter(center);

    Pointer p;
    p.setX(10);
    p.setY(10);

    position(circle, p);

	system("pause");
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1055444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

89、Redis 的 value 所支持的数据类型(String、List、Set、Zset、Hash)---->Zset 相关命令

本次讲解要点&#xff1a; ** Set相关命令&#xff1a;是指value中的数据类型** 启动redis服务器&#xff1a; 打开小黑窗&#xff1a; C:\Users\JH>e: E:>cd E:\install\Redis6.0\Redis-x64-6.0.14\bin E:\install\Redis6.0\Redis-x64-6.0.14\bin>redis-server.exe …

Android-Q 对 startActivity() 做了限制,怎么适配?

一. Q 禁用后台启动 Activity 今天来聊聊“Android Q 中后台禁止启动 Activity 对现有国内 App 中启动页设计的影响”这个话题&#xff0c;再聊聊 Android Q 限制后台启动 Activity 的具体细节。 有人可能会觉得 P 还没用上&#xff0c;Q 还远着。如果只是对于普通用户来说&a…

为什么要使用虚拟机?VMware安装使用

前言 大家好&#xff0c;本文是讲述了为什么需要使用虚拟机、使用虚拟机的好处&#xff0c;以及如何在Windows系统中安装VMware。希望对大家有所帮助~ 目录 前言一、为什么要安装使用虚拟机&#xff1f;1.1、什么是虚拟机&#xff1f;1.2、虚拟机的核心组件1.3、使用虚拟机的好…

【RabbitMQ】常用消息模型详解

文章目录 AMQP协议的回顾RabbitMQ支持的消息模型第一种模型(直连)开发生产者开发消费者生产者、消费者开发优化API参数细节 第二种模型(work quene)开发生产者开发消费者消息自动确认机制 第三种模型(fanout)开发生产者开发消费者 第四种模型(Routing)开发生产者开发消费者 第五…

网络-fetch

文章目录 前言一、fetch简介优点&#xff1a;缺点&#xff1a; 二、使用getpost进度实现取消请求超时实现 总结 前言 本文主要记录浏览器与服务端网络通讯 fetch 的介绍与使用&#xff0c;将完成get、post、进度、取消请求、和超时请求的功能实现。 一、fetch简介 fetch作为继…

基于自适应启动策略的混合交叉动态约束多目标优化算法(MC-DCMOEA)求解CEC2015/CEC2018/CEC2023(MATLAB代码)

一、动态多目标优化问题 1.1问题定义 1.2 动态支配关系定义 二、 基于自适应启动策略的混合交叉动态多目标优化算法 基于自适应启动策略的混合交叉动态多目标优化算法&#xff08;Mixture Crossover Dynamic Constrained Multi-objective Evolutionary Algorithm Based on Se…

深度学习(1)---卷积神经网络(CNN)

文章目录 一、发展历史1.1 CNN简要说明1.2 猫的视觉实验1.3 新认知机1.4 LeNet-51.5 AlexNet 二、卷积层2.1 图像识别特点2.2 卷积运算2.3 卷积核2.4 填充和步长2.5 卷积计算公式2.6 多通道卷积 三、池化层 一、发展历史 1.1 CNN简要说明 1. 卷积神经网络&#xff08;Convolut…

【51单片机编写占空比按秒渐亮与渐暗】2023-10-2

昨天刚在W10上安装CH340驱动&#xff0c;又下载到板子上LCD1602定时器时钟程序&#xff0c;为了调试&#xff0c;调用了一个LED观察控制蜂鸣器按秒响的变量&#xff0c;几经调试才发觉该开发板用的是有源蜂鸣器&#xff0c;不用IO取反操作&#xff0c;直接控制IO的高低电平即可…

手机号码格式校验:@Phone(自定义参数校验注解)

需求 新增接口 和 修改接口 中&#xff0c;手机号码的格式校验是普遍需要的。 在每个手机号码字段上添加正则表达式校验注解来实现校验&#xff0c;重复书写&#xff0c;容易出错&#xff1b;在不同的手机号码字段上&#xff0c;可能使用了不同的校验规则&#xff0c;无法有效…

2023年9月文章一览

2023年9月编程人总共更新了4篇文章&#xff1a; 1.2023年8月文章一览 2.Programming abstractions in C阅读笔记&#xff1a;p144-p160 3.Programming abstractions in C阅读笔记&#xff1a;p161-p165 4.我为什么选择这样一份经常出差的工作 9月份大部分时间在出差&#…

【论文阅读】Prototypical Networks for Few-shot Learning

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、论文摘要方法 二、视频总结 前言 本文结合论文和youtube上的视频[Few-shot learning][2.2] Prototypical Networks: intuition, algorithm, pytorch code来…

Spring Boot中的@Controller使用教程

一 Controller使用方法&#xff0c;如下所示&#xff1a; Controller是SpringBoot里最基本的组件&#xff0c;他的作用是把用户提交来的请求通过对URL的匹配&#xff0c;分配个不同的接收器&#xff0c;再进行处理&#xff0c;然后向用户返回结果。下面通过本文给大家介绍Spr…

Linux shell编程学习笔记5:变量命名规则、变量类型、使用变量时要注意的事项

跟其他的高级开发语言一样&#xff0c;Linux Shell编程中使用的数据也需要保存在变量中。 Shell使用变量来控制其行为&#xff0c;并且可以通过更改变量值来更改Shell和其他程序的行为。 我们先来了解一下变量命令的规则、变量类型和使用变量时要注意的事项。 一、变量命名规…

Redis学习笔记(常用数据类型,发布订阅,事务和锁机制,持久化,集群,雪崩,缓存击穿,分布式锁)

一、NoSQL数据库简介 解决扩展性问题&#xff0c;如果需要对功能进行改变&#xff08;比如增删功能&#xff09;&#xff0c;用框架有一定的规范要求&#xff0c;无形中解决了扩展性问题。 Redis是一种典型的NoSQL数据库。 NoSQL的基础作用&#xff1a; 1. nginx负载均衡反向…

3. 文档操作

1. 创建文档 1.1 创建一个文档 在相应的索引下面使用_doc创建文档&#xff0c;地址为&#xff1a;http://127.0.0.1:9200/students/_doc&#xff0c;创建一个姓名张三的学生信息&#xff1a; {"姓名":"张三","年级":5,"班级":2,&qu…

MySQL数据库——索引(6)-索引使用(覆盖索引与回表查询,前缀索引,单列索引与联合索引 )、索引设计原则、索引总结

目录 索引使用&#xff08;下&#xff09; 覆盖索引与回表查询 思考题 前缀索引 语法 示例 前缀长度 前缀索引的查询流程 单列索引与联合索引 索引设计原则 索引总结 1.索引概述 2.索引结构 3.索引分类 4.索引语法 5.SQL性能分析 6.索引使用 7.索引设计…

ORACLE Redo Log Buffer 重做日志缓冲区机制的设计

最近和朋友包括一些国产数据库的研发人员交流&#xff0c;很多程序员认为 Oracle 已经过时&#xff0c;开源数据库或者他们研发的国产数据库才代表数据库发展的未来。甚至在很多交流会议上拿出自家产品的某一个功能点和 Oracle 对比就觉得已经遥遥领先。 实际上数据库系统的发展…

Spring Cloud Alibaba Nacos 配置中心 (配置持久化与动态刷新) 实战

文章目录 一、配置持久化到DB1. 找到配置文件2. 修改配置文件3. 执行数据库SQL4. 控制台创建配置文件 二、集成Nacos配置中心客户端1. 引入依赖2. 添加配置信息3. 创建配置信息4. 编写测试类5. 运行测试6. 动态刷新配置 一、配置持久化到DB 1. 找到配置文件 找到 nacos 的安装…

C#,数值计算——Ranlim32的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// High-quality random generator using only 32-bit arithmetic.Same conventions /// as Ran.Period is 3.11E37 . Recommended only when 64-bit arithmetic is not /// a…

中国1km土壤特征数据集(2010年)

简介&#xff1a; 中国1km土壤特征数据集&#xff08;2010&#xff09;是基于第二次全国土壤调查的中国1:1000000比例尺土壤图和8595个土壤剖面图&#xff0c;以及美国农业部&#xff08;USDA&#xff09;中国区域土地和气候模拟标准&#xff0c;开发了一个多层土壤粒度分布数…