我们先来了解一下数据封装和数据抽象的概念。
数据封装是指将实现细节隐藏,仅暴露对外接口,归纳如下:
- 定义私有成员变量来放置数据,避免外界直接访问该变量
- 定义公有成员函数来访问私有成员变量,对外暴露接口
数据抽象是指将具体实现细节和概念分离,只呈现出必要的接口,归纳如下:
- 定义抽象类和纯虚函数来实现数据的抽象,将实际的实现交给子类
具体的实现过程如下:
- 定义类与访问控制
首先,我们定义一个类,并使用 public
和 private
关键词对成员变量和成员函数进行访问控制。其中 private
成员变量作为数据存储的载体,需要进行保护,无法直接被外界访问;而 public
成员函数允许外部代码与类进行交互,从而实现对封装的数据进行操作。
class Person
{
private:
string m_name;
int m_age;
public:
void setName(string name) { m_name = name; }
void setAge(int age) { m_age = age; }
string getName() { return m_name; }
int getAge() { return m_age; }
};
上述代码中,我们定义了 Person
类,并包含了两个私有成员变量 m_name
和 m_age
,分别用于存储人的姓名和年龄。同时,我们定义了四个公有成员函数:
setName
和setAge
用于设置私有成员变量值getName
和getAge
用于获取私有成员变量值
这样做的好处是,我们可以避免外部代码直接访问和操作私有成员变量,从而保证了数据的封装性。
- 定义抽象类与纯虚函数
接下来,我们将人员抽象为一个接口,并定义一个抽象类 IPerson
。我们在其中定义了一个纯虚函数 virtual void display() = 0;
,用于展示人员信息。纯虚函数没有实现语句,要求子类继承并实现它,从而将数据的具体实现委托给子类,实现数据的抽象。
class IPerson
{
public:
virtual void display() = 0;
};
class Student : public IPerson
{
private:
string m_name;
int m_age;
int m_score;
public:
Student(string name, int age, int score) : m_name(name), m_age(age), m_score(score) {}
virtual void display()
{
cout << "My name is " << m_name << ", I'm " << m_age << " years old, and my score is " << m_score << endl;
}
};
class Teacher : public IPerson
{
private:
string m_name;
int m_age;
string m_course;
public:
Teacher(string name, int age, string course) : m_name(name), m_age(age), m_course(course) {}
virtual void display()
{
cout << "My name is " << m_name << ", I'm " << m_age << " years old, and I teach " << m_course << endl;
}
};
上述代码中,我们定义了 IPerson
类,并包含一个纯虚函数 display
,子类必须继承并实现该函数。接着,我们定义了两个子类 Student
和 Teacher
,它们继承自 IPerson
并实现了 display
函数,以展示学生和老师的信息。这样一来,我们可以将具体实现交给子类,从而实现了数据的抽象。
下面是示例代码的完整实现,可以体验一下:
#include <iostream>
using namespace std;
class Person
{
private:
string m_name;
int m_age;
public:
void setName(string name) { m_name = name; }
void setAge(int age) { m_age = age; }
string getName() { return m_name; }
int getAge() { return m_age; }
};
class IPerson
{
public:
virtual void display() = 0;
};
class Student : public IPerson
{
private:
string m_name;
int m_age;
int m_score;
public:
Student(string name, int age, int score) : m_name(name), m_age(age), m_score(score) {}
virtual void display()
{
cout << "My name is " << m_name << ", I'm " << m_age << " years old, and my score is " << m_score << endl;
}
};
class Teacher : public IPerson
{
private:
string m_name;
int m_age;
string m_course;
public:
Teacher(string name, int age, string course) : m_name(name), m_age(age), m_course(course) {}
virtual void display()
{
cout << "My name is " << m_name << ", I'm " << m_age << " years old, and I teach " << m_course << endl;
}
};
int main()
{
// Example 1: Encapsulation
Person person;
person.setName("John");
person.setAge(30);
cout << "My name is " << person.getName() << ", I'm " << person.getAge() << " years old" << endl;
// Example 2: Abstraction
IPerson* student = new Student("Alex", 20, 90);
student->display();
IPerson* teacher = new Teacher("Bob", 40, "Math");
teacher->display();
return 0;
}
输出结果为:
My name is John, I'm 30 years old
My name is Alex, I'm 20 years old, and my score is 90
My name is Bob, I'm 40 years old, and I teach Math
可以看到,我们成功地封装了学生和老师的数据,同时实现了数据的抽象。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详细分析C++ 数据封装和数据抽象 - Python技术站