C++ 类和对象(一): 封装
c++面向对象的三大特性:封装,继承,多态
c++认为万事皆可为对象,对象上有其属性和行为
例如:
对象: 车
属性: 轮胎,方向盘,喇叭,车灯
行为:载人,驾驶,照明
具有相同性质的对象,抽象位类
车属于车类
1. 封装的意义
• 将属性和行为作为一个整体,表现生活中的事物,即对象
• 将属性和行为加以权限的控制(private, protected, public)
1.1 意义1:
在设计类的时候,可以将属性和行为写在一起,表现事物
- 实例化: 通过类来创建对象的过程
- 类中的属性和行为统称为 成员
- 属性: 成员属性 成员变量
- 行为: 成员函数 成员方法
语法:
class 类名{
访问权限:
属性 / 行为
};
实例1: 设计一个圆类,求圆的周长
//创建一个圆,并计算周长
#include <iostream>
using namespace std;
#define PI 3.14
//公式: 周长 = 2 * PI * r
class Circle {
//权限
public:
//属性
int m_r;
//行为
double calculateC()
{
return 2 * PI * m_r;
}
};
int main()
{
//通过类,创建具体的对象(圆)
Circle c;
//给对象的属性赋值
c.m_r = 10;
cout << "圆的周长是: " << c.calculateC() << endl;
system("pause");
return 0;
}
1.2 意义2:
类在设计时候,可以把属性和行为放在不同的权限下,加以控制
访问权限:
名称 | 权限 | 权限 | 权限 |
---|---|---|---|
public | 类内可以访问 | 类外可以访问 | |
protected | 类内可以访问 | 类外不可以访问 | 子类可以访问父类中的保护成员 |
private | 类内可以访问 | 类外不可以访问 | 子类不可以访问父类中的私有成员 |
protected 和 private
儿子可以开父亲的汽车
儿子不可以知道父亲的银行卡密码
举例
#include <iostream>
using namespace std;
class Person {
public:
string m_Name;
protected:
string m_Car;
private:
int m_password;
public:
void func()
{
m_Name = "Jerry";
//类内可以访问
m_Car = "Audi";
m_password = 1234;
}
};
int main()
{
Person p;
p.m_Name = "Ross";
p.m_Car = "BWM";//报错,类外不可以访问
p.m_password = "4321";//报错,类外不可以访问
system("pause");
return 0;
}
2. struct 和class的区别
在C++中唯一的区别在于默认的访问权限不同
• struct的默认权限为public
• class的默认权限为 private
#include <iostream>
using namespace std;
class C {
int m_c; //默认权限是私有的
};
struct S {
int m_s;//默认权限为公共
};
int main()
{
C c;
c.m_c = 100;//报错,为私有,不可访问
S s;
s.m_s = 100;//正确,访问权限为公共
system("pause");
return 0;
}
3. 成员属性设为私有
优点1: 将所有成员属性设置为私有,可以自己控制读写权限
优点2: 对于写权限(比如修改一个数据,防止超出有效范围),我们可以检测数据的有效性
对外提供一个公共的成员函数,来给成员属性进行赋值操作
class Person {
public:
//写权限
void setName(string name)
{
m_Name = name;
}
//读权限
string getName()
{
return m_Name;
}
void setAge(int age)
{ //可以设置写入范围限制
if (age < 0 || age > 150)
{
m_Age = 0;
cout << "输入有误" << endl;
return;
}
m_Age = age;
}
int getAge()
{
return m_Age;
}
private:
string m_Name = "Jerry";
int m_Age = 0;
};
int main()
{
Person p;
p.setName("Mark");
cout << "name is : " << p.getName() << endl;
p.setAge(200);
cout << "age is : " << p.getAge() << endl;
p.setAge(20);
cout << "age is : " << p.getAge() << endl;
system("pause");
return 0;
}
4. 练习案例:
设计立方体:
设计立方体类(Cube)
求出立方体的面积和体积
分别用全局函数和成员函数判断两个立方体体积是否相等
用引用的方式直接使用原始的数据,就不需要拷贝一份数据出来了
class Cube {
public:
//行为
int getS()
{
return (m_H * m_W + m_H * m_L + m_W * m_L) * 2;
}
int getV()
{
return m_L * m_W * m_H;
}
//利用成员函数判断俩个立方体体积是否相等
bool isSameByClass(Cube c)
{
if (this->getV() == c.getV())
return true;
else
return false;
}
void setH(int h)
{
m_H = h;
}
void setW(int w)
{
m_W = w;
}
void setL(int l)
{
m_L = l;
}
private:
//属性
int m_H;
int m_W;
int m_L;
};
//全局函数判断体积是否相等
bool isSame(Cube& c1, Cube& c2)
{
if (c1.getV() == c2.getV())
return true;
else
return false;
}
int main()
{
Cube c1;
c1.setH(2);
c1.setL(3);
c1.setW(4);
cout << "c1面积是: " << c1.getS() << endl;
cout << "c1体积是: " << c1.getV() << endl;
Cube c2;
c2.setH(2);
c2.setL(3);
c2.setW(41);
cout << "c2面积是: " << c2.getS() << endl;
cout << "c2体积是: " << c2.getV() << endl;
//全局函数
bool ret0 = isSame(c1, c2);
if (ret0)
cout << "全局函数判断 c1 和 c2 体积相等" << endl;
else
cout << "全局函数判断 c1 和 c2 体积不相等" << endl;
//成员函数判断
bool ret1 = c1.isSameByClass(c2);
if (ret1)
cout << "成员函数判断 c1 和 c2 体积相等" << endl;
else
cout << "成员函数判断 c1 和 c2 体积不相等" << endl;
system("pause");
return 0;
}