9.4 类和对象
C++面向对象的三大特性为:封装、继承、多态
C++认为万事万物皆为对象,对象有其属性和行为。
*例如:
人可以作为对象,属性有姓名、年龄、身高、体重…,行为:走,跑跳、吃饭、唱歌…
车也可以作为对象,属性有:轮胎、方向盘、车灯、
行为有:载人、放音乐、开空调…
总结:有相同性质的对象,我们可以抽象为类,人属于人类,车属于车类
9.4.1 封装
1、封装的意义
封装是C++面向对象三大特性之一。
封装的意义:
- 将属性和行为作为一个整体,表现生活中的事物。
- 将属性和行为加以权限控制。
封装意义1:
在设计类的时候,属性和行为写在一起,表现事物
属性:通常为一些变量
行为:通过变量运算得到的功能函数
**语法:**class 类名{ 访问权限 :行为/属性};
//同一个东西,不同名称 //类中的属性和行为,我们统一称为成员 // 属性--成员属性--成员变量 // 行为--成员函数--成员方法
**示例1:**设计一个圆类,求圆的周长
示例代码:
#include<iostream>
using namespace std;
//圆周率
const double Pi = 3.14;//const修饰防止被改变
//设计一个圆类,求圆的周长
//圆求周长的公式:2*Pi*r
//class 代表设计一个类,类后面紧跟着就是类名称
class Circle
{
//访问权限
//公共权限
public:
//属性:通常为一些变量
double r;
//行为:通常为一些功能函数
//获取圆的周长
double calculateZC()
{
return 2 * Pi * r;
}
private:
};
int main()
{
//通过圆类,创建具体的圆(对象)
//实例化 (通过一个类,创建一个对象的过程)
Circle cl1;
//给圆对象的属性进行赋值
cl1.r = 10.0;
//调用类的行为操作:2*3.14*10=62.8
cout << "圆的周长为:" << cl1.calculateZC() << endl;
system("pause");
return 0;
}
运行结果:
**示例2:**设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号。
示例代码:
#include<iostream>
#include<string>
using namespace std;
//设计学生类
class Student
{
//公共权限
public:
//类中的属性和行为,我们统一称为成员
// 属性--成员属性--成员变量
// 行为--成员函数--成员方法
//属性:姓名和学号
string name;
int number;
//行为:打印学生信息
void print()
{
cout << "姓名:" << name << endl;
cout << "学号:" << number << endl;
}
//通过行为给属性进行赋值操作
//给学生姓名赋值
void Set_name(string M_name)
{
name = M_name;
}
//给学生学号赋值
void Set_number(int M_number)
{
number = M_number;
}
};
int main()
{
//示例化:
Student s1;
//给实例化对象赋值
//s1.name = "廖克志";
//s1.number = 1900301026;
cout << "请输入你的姓名:" << endl;
cin >> s1.name;
cout << "请输入你的学号:" << endl;
cin >> s1.number;
cout << "张三信息:" << endl;
//调用类的行为
s1.print();
Student s2;
s2.name = "李四";
s2.number = 5323;
cout << "张三信息:" << endl;
s2.print();
Student s3;
s3.Set_name("王五");
s3.Set_number(123456);
cout << "张三信息:" << endl;
s3.print();
system("pause");
return 0;
}
运行结果:
2、封装意义2
类在设计时,可以把属性和行为放在不同的权限下,加以控制
访问权限有三种:
- public 公共权限 成员 类内可以访问,类外也可以访问
- protected 保护权限 成员 类内可以访问,类外不可以访问 子类可以访问父类中的保护内容
- private 私有权限 成员 类内可以访问,类外不可以访问 子类不可以访问父类中的私有内容
#include<iostream>
using namespace std;
//3种权限访问
//公共权限 public 成员 类内可以访问,类外也可以访问
//保护权限 protected 成员 类内可以访问,类外不可以访问 子类可以访问父类中的保护内容
//私有权限 private 成员 类内可以访问,类外不可以访问 子类不可以访问父类中的私有内容
//人类
class Person
{
public:
//姓名 公共权限
string name;
protected:
//汽车 保护权限
string car;
private:
//银行卡密码 私有权限
int password;
//公共行为,类内和类外都可以访问
public:
void func()
{
name = "张三";
car = "奔驰";
password = 133564;
cout << name << " " << car << " " << password << endl;
}
};
int main()
{
//实例化具体对象
Person p1;
cout << "修改前:" << endl;
p1.func();
p1.name = "廖克志";
//p1.car = "奔驰4s"; //保护权限的内容,在类外访问不到
//p1.password = 554131;//私有权限内容,类外访问不到
cout << "修改后:" << endl;
p1.func();
system("pause");
return 0;
}
运行结果:
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 默认权限为公共
//class 默认权限为私有
C1 c1;
//c1.m_A = 100;//在class中默认权限是私有,外部可以访问
C2 c2;
c2.m_B = 200;//在struct中默认权限是公共,所以外部可以访问
system("pause");
return 0;
}
运行结果:
无报错
3、成员属性私有化
**优点1:**将所有成员属性设置为私有,可以自己控制读写权限
**优点2:**对于读写权限,我们可以检测数据的有效性。
示例:
#include<iostream>
using namespace std;
#include<string>
//成员属性设置为私有化
//1、可以自己控制读写权限
//2、对于写可以检测数据的有效性
class Person
{
public:
//对外提供公共接口
void SetName(string name)
{
m_name = name;
}
string getName()
{
return m_name;
}
//年龄只读--获取年龄
int getAge()
{
m_age = 0;
return m_age;
}
//获取年龄,可读可写 如果想修改,年龄范围必须是0~150之间(对年龄范围做一个限定)
int getAge2()
{
return m_age;
}
//设置年龄
void SetAge2(int age)
{
if (age < 0 || age>150)
{
m_age = 0;
cout << "你输入的年龄不在范围内。请重新输入" << endl;
return;
}
m_age = age;
}
//设置情人 只写
void SetLover(string name)
{
/*现在异常*/
m_lover = name;
}
private:
//私有属性
//
//姓名 可读可写
string m_name;
//年龄 只读
int m_age;
//对象 只写
string m_lover;
};
int main()
{
//实例化一个对象
Person p1;
p1.SetName ("张三");
cout << "姓名:" << p1.getName() << endl;
cout << "年龄:" << p1.getAge() << endl;
//设置情人为:辣妹
p1.SetLover("李四");
//cout << "情人为:" << p1.getLover() << endl; //外部是不可以访问的,只有写权限
//2、对于写可以检测数据的有效性
p1.SetAge2(1000);
cout << "年龄:" << p1.getAge() << endl;
system("pause");
return 0;
}
运行结果:
练习案例1:设计立方体类
设计立方体类(cube)
求出立方体的面积和体积
分别用全局函数和成员函数判断两个立方体是否相等。
示例代码:
#include<iostream>
using namespace std;
//立方体类设计案例
//1、创建立方体类
//2、设计属性
//3、设计行为,获取立方体面积和体积
//4、分别利用全局函数和成员函数,判断两个立方体是否相等
class Cube
{
public:
//设置长
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 calculateS()
{
return 2 * (m_H * m_L + m_H * m_W + m_L * m_W);
}
//获取立方体的体积
int calculateV()
{
return m_H * m_L * m_W;
}
//利用成员函数判断两个立方体是否相等,只需要传一个参数即可
bool isSameByClass(Cube& c)
{
if (m_H== c.getH() && m_L == c.getL() && m_W == c.getW())
{
return true;
}
else return false;
}
private:
int m_L; //长
int m_W;//宽
int m_H;//高
};
//利用全局函数判断,两个立方体是否相等
bool isSame(Cube& c1, Cube c2)
{
if (c1.getH() == c2.getH() && c1.getL() == c2.getL() && c1.getW() == c2.getW())
{
return true;
}
else return false;
}
int main()
{
//创建立方体对象
Cube c1;
//用简单的数据进行测试,看运行是否正确
c1.setH(10);
c1.setL(10);
c1.setW(10);
cout << "立方体的面积为:" << c1.calculateS() << endl;
cout << "立方体的体积为:" << c1.calculateV() << endl;
//创建立方体对象c2
Cube c2;
c2.setH(10);
c2.setL(10);
c2.setW(20);
//利用全局函数判断
bool ret1 = isSame(c1, c2);
if (ret1)
{
cout << "全局函数判断:两个立方体的相等" << endl;
}
else
{
cout << "全局函数判断:两个立方体不相等" << endl;
}
//利用成员函数进行判断
bool ret2 = c1.isSameByClass(c2);
if (ret2)
{
cout << "成员函数判断:两个立方体的相等" << endl;
}
else
{
cout << "成员函数判断:两个立方体不相等" << endl;
}
system("pause");
return 0;
}
运行结果:
练习案例2:点和圆的关系
设计一个圆形类(Circle),和一个点类(Point),计算点和圆的关系。
本项目案例包含以下5个文件:
Point.h
#pragma once //防止头文件重复包含
#include<iostream>
using namespace std;
class Point
{
public:
//设置x
void setX(int x);
//获取x
int getX();
//设置y
void setY(int y);
//获取x
int getY();
private:
//点的坐标x和y
int m_X;
int m_Y;
};
Point.cpp
#include"Point.h"
//必须指明函数为Point::作用域下的函数
void Point::setX(int x)
{
m_X = x;
}
//获取x
int Point::getX()
{
return m_X;
}
//设置y
void Point::setY(int y)
{
m_Y = y;
}
//获取x
int Point::getY()
{
return m_Y;
}
Circle.h
#pragma once
#include<iostream>
#include"Point.h"
using namespace std;
//设计一个圆类
class Circle
{
public:
//设置半径R
void setR(int r);
//获取半径
int getR();
//设置圆心
void setCenter(Point center);
//获取圆心
Point getCenter();
private:
int m_R;//半径
//在类中可以让另一个类作为本类的成员
Point M_Center;//圆心
};
Circle.cpp
#include"Point.h"
//必须指明函数为Point::作用域下的函数
void Point::setX(int x)
{
m_X = x;
}
//获取x
int Point::getX()
{
return m_X;
}
//设置y
void Point::setY(int y)
{
m_Y = y;
}
//获取x
int Point::getY()
{
return m_Y;
}
main.cpp
#include<iostream>
using namespace std;
#include"Circle.h"
#include"Point.h"
//点和圆的关系案例
//点类
/*
class Point
{
public:
//设置x
void setX(int x)
{
m_X = x;
}
//获取x
int getX()
{
return m_X;
}
//设置y
void setY(int y)
{
m_Y = y;
}
//获取x
int getY()
{
return m_Y;
}
private:
//点的坐标x和y
int m_X;
int m_Y;
};
//设计一个圆类
class Circle
{
public:
//设置半径R
void setR(int r)
{
m_R = r;
}
//获取半径
int getR()
{
return m_R;
}
//设置圆心
void setCenter(Point center)
{
M_Center = center;
}
//获取圆心
Point getCenter()
{
return M_Center;
}
private:
int m_R;//半径
//在类中可以让另一个类作为本类的成员(核心点)
Point M_Center;//圆心
};*/
//判断点和圆的关系
void isInCircle(Circle& c, Point& p)
{
//计算两点距离的平方
int distance=
(c.getCenter().getX() - p.getX())* (c.getCenter().getX() - p.getX()) +
(c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY());
//计算半径
int R_distance = c.getR()*c.getR();
//判断圆心与点的比较
if (R_distance == distance)
{
cout << "点在圆上" << endl;
}
else if (R_distance < distance)
{
cout << "点在圆外" << endl;
}
if (R_distance > distance)
{
cout << "点在圆内" << endl;
}
}
int main()
{
//创建一个圆
Circle c1;
//设置圆心坐标
Point center;
center.setX(10);
center.setY(0);
c1.setCenter(center);
//设置圆的半径
c1.setR(10);
//创建一个点
Point p;
//设置点的坐标
p.setX(10);
p.setY(8);
//判断它们之间的关系
isInCircle(c1, p);
system("pause");
return 0;
}
运行结果:
上一篇:19C++函数提高篇