C++核心入门-04类和对象(1)-封装
4.0 前言
C++面向对象的三大特性为:封装、继承和多态。
C++认为万事万物皆为对象,对象有其属性和行为。
例如:
(1)人可以作为对象,属性有姓名、年龄、身高、体重…,行为有走、跑、吃饭、唱歌 …
(2)车也可以作为对象,属性有轮胎、方向盘、车灯 … ,行为有载人、放音乐、开空调…
具有相同性质的对象,我们可以抽象为类,人属于人类,车属于车类。
4.1 封装
4.1.1 封装的意义
封装是C++面向对象三大特性之一
封装的意义:
- 将属性和行为作为一个整体,表现生活中的事物;
- 将属性和行为加以权限控制。
(1)意义一:在设计类时,属性和行为写在一起,表现事物
语法:class 类名{ 访问权限:属性 / 行为};
注意:属性一般是变量;行为一般是函数
实例化 (通过一个类,来创建一个对象的过程)
例子1:设计一个圆类,求出圆的周长
#include<iostream>
using namespace std;
//圆周率
const double PI = 3.14;
//设计一个圆类,求圆的周长
//class代表设计一个类,类后面紧跟着的是类名称
class Circle
{
//访问权限
//公共权限
public:
//属性(一般用变量)
int m_r;
//行为(一般用函数)
double calculateZC()
{
return 2 * PI*m_r;
}
};
int main()
{
//通过圆类 创建具体的圆(对象)
//实例化 (通过一个类,来创建一个对象的过程)
Circle c1;
//给圆对象 的属性进行赋值
c1.m_r = 10;
cout << "圆的周长为:" << c1.calculateZC() << endl;
system("pause");
return 0;
}
运行结果:
也通过函数给属性进行赋值操作。
例子2:设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号。
#include<iostream>
#include<string>
using namespace std;
class Student
{
public ://公共权限
//属性
string m_name;
long long m_id;
//行为
void showStudent()
{
cout << "name:" << m_name << " ID:" << m_id << endl;
}
//通过函数给属性进行赋值操作
//给姓名赋值
void setname(string name)
{
m_name = name;
}
//给学号赋值
void set_id(long long id)
{
m_id = id;
}
};
int main()
{
//实例化对象
Student stu1;
stu1.set_id(170113030107);
stu1.setname("张三");
stu1.showStudent();
system("pause");
return 0;
}
注意:
类中的属性和行为 我们同一称为成员
属性也叫成员属性或者成员变量;
行为也叫成员函数或者成员方法。
(2)意义二、类在设计时,可以把属性和行为放在不同的权限下,加以控制
访问权限有三种:
- 公共权限 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 = 111;
}
};
4.1.2 struct和class的区别
在C++中,struct和class的唯一区别在于它们的默认权限不同:
- struct的默认权限是公共
- class的默认权限是私有
示例:
#include<iostream>
using namespace std;
class C1
{
int m_a;//默认权限 私有
};
struct C2
{
int m_b;//默认权限 公共
};
int main()
{
//struct和class区别
//struct默认权限是 公共 public
//class默认权限是 私有 private
C1 c1;
c1.m_a = 100;//class里默认的权限是私有,因此类外不可以访问
C2 c2;
c2.m_b = 200;//在struct中默认的权限是公共,因此类外可以访问
system("pause");
return 0;
}
4.1.3 成员属性设置为私有
优点:
- 将所有成员属性设置为私有,可以自己控制读写权限;
- 对于写权限,我们可以检测数据的有效性
例如:
设计一个人类,其中属性都为私有:
(1)m_Name : 可读可写
(2)m_Age: 只读
(3)m_Lover: 只写
示例代码:
#include<iostream>
#include<string>
using namespace std;
//成员属性设置为私有
//1、可以自己控制读写权限
//2、对于写,可以检测数据的有效性
//设计人类
class Person
{
public:
//设置姓名
void setName(string name)
{
m_Name = name;
}
//获取姓名
string getName()
{
return m_Name;
}
//获取年龄 只读
int getAge()
{
return m_Age = 30;
}
//设置情人 只写
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;
cout << "年龄:" << p.getAge() << endl;
p.setLover("李二狗");
system("pause");
return 0;
}
练习案例1:设计长方体类
要求:
设计长方体类(Cube)
求出长方体的面积和体积
分别用全局函数和成员函数判断两个立方体是否相等。
示例代码:
#include<iostream>
using namespace std;
//长方体类设计
//1、创建长方体类
//2、设计属性
//3、设计行为 获取长方体面积和体积
//4、分别利用全局函数和成员函数 判断两个长方体是否相等
class Cube
{
public:
//设置长
void setm_L(int l)
{
m_L = l;
}
//获取长
int getm_L()
{
return m_L;
}
//设置宽
void setm_W(int w)
{
m_W = w;
}
//获取宽
int getm_W()
{
return m_W;
}
//设置高
void setm_H(int h)
{
m_H = h;
}
//获取高
int getm_H()
{
return m_H;
}
//获取长方体面积
int calculate_S()
{
return 2 * (m_L*m_W + m_W * m_H + m_L * m_H);
}
//获取长方体体积
int calculate_V()
{
return m_L * m_W*m_H;
}
//利用成员函数来判断两个立方体是否相等
bool isSameByClass(Cube &C2)
{
if (m_L == C2.getm_L() && m_W == C2.getm_W() && m_H == C2.getm_H())
{
return true;
}
else
{
return false;
}
}
private:
int m_L;//长
int m_W;//宽
int m_H;//高
};
//利用全局函数判断 两个长方体是否相等(这里不太严谨,没有考虑顺序哈)
bool isSame(Cube &C1, Cube &C2)
{
if (C1.getm_L() == C2.getm_L() && C1.getm_W() == C2.getm_W() && C1.getm_H() == C2.getm_H())
{
return true;
}
else
{
return false;
}
}
int main()
{
//创建长方体
Cube C1;
C1.setm_L(10);
C1.setm_W(10);
C1.setm_H(10);
cout << "长方体的面积:" << C1.calculate_S() << endl;
cout << "长方体的体积:" << C1.calculate_V() << endl;
//创建第二个长方体
Cube C2;
C2.setm_L(10);
C2.setm_W(10);
C2.setm_H(2);
//利用全局函数判断
bool ret = isSame(C1, C2);
if (ret)
{
cout << "全局函数判断:C1和C2是相等的" << endl;
}
else
{
cout << "全局函数判断:C1和C2不相等" << endl;
}
bool ret2 = C1.isSameByClass(C2);
if (ret2)
{
cout << "成员函数判断:C1和C2是相等的" << endl;
}
else
{
cout << "成员函数判断:C1和C2不相等" << endl;
}
//利用成员函数判断
system("pause");
return 0;
}
运行结果:
练习案例2 :点和圆的关系
设计一个圆类(Circle),和一个点类(Point),计算点和圆的关系:
示例:
#include<iostream>
using namespace std;
点和圆关系案例
//点类
class Point
{
public:
//设置X坐标
void set_X(int x)
{
m_X = x;
}
//获取X坐标
int get_X()
{
return m_X;
}
//设置Y坐标
void set_Y(int y)
{
m_Y = y;
}
//获取Y坐标
int get_Y()
{
return m_Y;
}
private:
int m_X;
int m_Y;
};
//圆类
class Circle
{
public:
//设置半径
void set_R(int r)
{
m_R = r;
}
//获取半径
int get_R()
{
return m_R;
}
//设置圆心
void set_Center(Point center)
{
m_Center = center;
}
//获取圆心
Point get_Center()
{
return m_Center;
}
private:
int m_R;//半径
//在类中,可以让另一个类 作为本类中的成员
Point m_Center;//圆心
};
//判断点和圆的关系
void isInCircle(Circle &c, Point &p)
{
//计算两点之间的距离平方
int S2 = (c.get_Center().get_X() - p.get_X())* (c.get_Center().get_X() - p.get_X()) +
(c.get_Center().get_Y() - p.get_Y()) *(c.get_Center().get_Y() - p.get_Y());
//计算半径的平方
int R2 = (c.get_R())*(c.get_R());
//判断
if (S2<R2)
{
cout << "点在圆内" << endl;
}
else if(S2==R2)
{
cout << "点在圆上" << endl;
}
else
{
cout << "点在圆外" << endl;
}
}
int main()
{
//创建圆
Circle c1;
c1.set_R(10);
Point center;
center.set_X(10);
center.set_Y(0);
c1.set_Center(center);
//创建点
Point p1;
p1.set_X(10);
p1.set_Y(11);
isInCircle(c1, p1);
system("pause");
return 0;
}
注意:在类中,可以让另一个类 作为本类中的成员
运行结果:
改进:这里我也没有学明白!!!!!!!
大致就是将点类和圆类分文件编写,只用在主函数所在的cpp文件中添加上点类圆类的头文件即可。
(1)创建point.h和point.cpp文件
point.h
#pragma once//避免同一头文件,被包含多次
#include<iostream>
using namespace std;
//点类
class Point
{
public:
//这里只对成员函数做声明
//设置X坐标
void set_X(int x);
//获取X坐标
int get_X();
//设置Y坐标
void set_Y(int y);
//获取Y坐标
int get_Y();
private:
int m_X;
int m_Y;
};
point.cpp
#include"point.h"
//点类
//设置X坐标
void Point::set_X(int x)
{
m_X = x;
}
//获取X坐标
int Point::get_X()
{
return m_X;
}
//设置Y坐标
void Point::set_Y(int y)
{
m_Y = y;
}
//获取Y坐标
int Point::get_Y()
{
return m_Y;
}
Point::表示在点域之下进行操作
(2)创建circle.h和circle.cpp文件
circle.h
#pragma once
#include<iostream>
#include"point.h"//因为这里面圆心用到了点类
using namespace std;
//圆类
class Circle
{
public:
//设置半径
void set_R(int r);
//获取半径
int get_R();
//设置圆心
void set_Center(Point center);
//获取圆心
Point get_Center();
private:
int m_R;//半径
//在类中,可以让另一个类 作为本类中的成员
Point m_Center;//圆心
};
circle.cpp
#include"circle.h"
//判断点和圆的关系
void isInCircle(Circle &c, Point &p)
{
//计算两点之间的距离平方
int S2 = (c.get_Center().get_X() - p.get_X())* (c.get_Center().get_X() - p.get_X()) +
(c.get_Center().get_Y() - p.get_Y()) *(c.get_Center().get_Y() - p.get_Y());
//计算半径的平方
int R2 = (c.get_R())*(c.get_R());
//判断
if (S2<R2)
{
cout << "点在圆内" << endl;
}
else if(S2==R2)
{
cout << "点在圆上" << endl;
}
else
{
cout << "点在圆外" << endl;
}
}
int main()
{
//创建圆
Circle c1;
c1.set_R(10);
Point center;
center.set_X(10);
center.set_Y(0);
c1.set_Center(center);
//创建点
Point p1;
p1.set_X(10);
p1.set_Y(11);
isInCircle(c1, p1);
system("pause");
return 0;
}
运行结果也是一样的。