抽象的理解

一、抽象的概念

面向对象方法中的抽象,是指对具体问题(对象)进行概括,提取出一类对象的公共性质并加以描述的过程。抽象是面向对象程序设计的第一步,也是定义类的基础。

抽象通常包含两个方面:

抽象类型关注点说明对应到类中
数据抽象是什么对象的属性特征、状态数据成员(变量)
行为抽象能做什么对象的功能作用、操作成员函数(方法)

二、示例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)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注