一、抽象的概念
面向对象方法中的抽象,是指对具体问题(对象)进行概括,提取出一类对象的公共性质并加以描述的过程。抽象是面向对象程序设计的第一步,也是定义类的基础。
抽象通常包含两个方面:
| 抽象类型 | 关注点 | 说明 | 对应到类中 |
|---|---|---|---|
| 数据抽象 | 是什么 | 对象的属性特征、状态 | 数据成员(变量) |
| 行为抽象 | 能做什么 | 对象的功能作用、操作 | 成员函数(方法) |
二、示例1:时钟的抽象
以一个简单的时钟程序为例。通过对时钟进行分析:
- 数据抽象:时钟需要记录当前时间,时间由时、分、秒三个整数构成。
int hour; // 时
int minute; // 分
int second; // 秒Code language: JavaScript (javascript)
- 行为抽象:时钟需要具备显示时间和设置时间的功能。
void showTime(); // 显示当前时间
void setTime(); // 设置时间Code language: JavaScript (javascript)
将数据和功能组合在一起,就构成了”时钟类”的抽象:
class Clock
{
private:
int hour;
int minute;
int second;
public:
void showTime();
void setTime(int h, int m, int s);
};Code language: JavaScript (javascript)
三、示例2:人的抽象
通过对人进行归纳和抽象,提取出共性:
- 数据抽象(共同属性):姓名、性别、年龄等。
string name; // 姓名
string sex; // 性别
int age; // 年龄Code language: JavaScript (javascript)
- 行为抽象(共同行为):包括吃饭、行走等生物行为,以及工作、学习等社会行为。
void eat(); // 吃饭
void walk(); // 行走
void work(); // 工作
void study(); // 学习Code language: JavaScript (javascript)
四、同一对象因研究侧重点不同产生不同的抽象结果
抽象不是一成不变的,同一个现实对象,针对不同的应用场景和问题需求,关心的特征不同,抽象出的类也不同。
以”人”为例:
| 应用场景 | 关心的特征(数据抽象) | 关心的行为(行为抽象) |
|---|---|---|
| 人事管理软件 | 姓名、性别、年龄、工龄、工资、工作部门、工作能力、上下级隶属关系 | 入职、调岗、晋升、计算工资、考核 |
| 医院管理系统 | 姓名、性别、年龄、病历号、过敏史、诊断记录、处方 | 挂号、诊断、开处方、缴费、取药 |
| 学校教务系统 | 姓名、学号、班级、专业、成绩、选课记录 | 选课、考试、查询成绩、打印成绩单 |
| 社交软件 | 昵称、头像、个性签名、好友列表、在线状态 | 发消息、加好友、发动态、点赞 |
这说明:抽象取决于你从什么角度、解决什么问题。没有”唯一正确”的抽象,只有”适合当前需求”的抽象。
五、代码示例
以下代码演示了同一现实对象(学生)在不同场景下的不同抽象方式:
#include <iostream>
#include <string>
using namespace std;
// ===== 场景1:教务管理视角下的学生 =====
class StudentAcademic
{
private:
string name;
string studentID;
string major;
double gpa;
public:
void setName(string n) { name = n; }
void setStudentID(string id) { studentID = id; }
void setMajor(string m) { major = m; }
void setGPA(double g) { gpa = g; }
void enrollCourse(string courseName)
{
cout << name << " 选修了课程:" << courseName << endl;
}
void displayTranscript()
{
cout << "学生:" << name << ",学号:" << studentID
<< ",专业:" << major << ",GPA:" << gpa << endl;
}
};
// ===== 场景2:宿舍管理视角下的学生 =====
class StudentDormitory
{
private:
string name;
string dormNumber;
string checkInDate;
bool isCurfew;
public:
void setName(string n) { name = n; }
void setDormNumber(string d) { dormNumber = d; }
void setCheckInDate(string d) { checkInDate = d; }
void checkIn()
{
cout << name << " 入住宿舍 " << dormNumber << endl;
}
void reportCurfew()
{
isCurfew = true;
cout << name << " 已归寝" << endl;
}
};
// ===== 场景3:时钟类(完整实现) =====
class Clock
{
private:
int hour;
int minute;
int second;
public:
void setTime(int h, int m, int s)
{
if (h >= 0 && h < 24) hour = h;
else hour = 0;
if (m >= 0 && m < 60) minute = m;
else minute = 0;
if (s >= 0 && s < 60) second = s;
else second = 0;
}
void showTime()
{
if (hour < 10) cout << "0";
cout << hour << ":";
if (minute < 10) cout << "0";
cout << minute << ":";
if (second < 10) cout << "0";
cout << second << endl;
}
void tick()
{
second++;
if (second >= 60)
{
second = 0;
minute++;
if (minute >= 60)
{
minute = 0;
hour++;
if (hour >= 24)
hour = 0;
}
}
}
};
int main()
{
// 测试时钟
Clock c;
c.setTime(9, 30, 0);
cout << "当前时间:";
c.showTime();
c.tick();
cout << "一秒后:";
c.showTime();
cout << endl;
// 测试教务视角学生
StudentAcademic sa;
sa.setName("张三");
sa.setStudentID("20230001");
sa.setMajor("计算机科学");
sa.setGPA(3.8);
sa.enrollCourse("C++程序设计");
sa.displayTranscript();
cout << endl;
// 测试宿舍视角学生
StudentDormitory sd;
sd.setName("张三");
sd.setDormNumber("A栋302");
sd.setCheckInDate("2023-09-01");
sd.checkIn();
sd.reportCurfew();
return 0;
}Code language: PHP (php)