【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来!
《项目案例分享》
《极客DIY开源分享》
《嵌入式通用开发实战》
《C++语言开发基础总结》
《从0到1学习嵌入式Linux开发》
《QT开发实战》
《Android开发实战》
《实用硬件方案设计》
《结构建模设计》
《数据库开发总结》
《JAVA入门基础》
《JavaWeb开发实战》
长期持续带来更多案例与技术文章分享;
欢迎商业项目咨询,10年+软硬全栈内功,助力解决您的尊贵需求。
原文链接:https://winter.blog.csdn.net/article/details/129418745
——————————————————————————————————
目录
0 引言
1 数据封装
2 数据抽象
3 接口(抽象类)
4 总结
0 引言
这一次的博文总结下数据封装、数据抽象与接口,其实有之前博文的基础这里也很容易理解。封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制, C++ 通过创建类来支持封装和数据隐藏(public、protected、 private)。
1 数据封装
数据封装是一种把数据和操作数据的函数捆绑在一起的机制,在 C++程序中,任何带有公有和私有成员的类都可以作为数据封装和数据抽象的实例。 通常情况下,我们都会设置类成员状态为私有(private),除非我们真的需要将其暴露,这样才能保证良好的封装性。这通常应用于数据成员,但它同样适用于所有成员,包括虚函数。
下面举个例子,看下数据封装的使用方法,其实就是合理的使用public、private。
以People类为例,增加一个吃苹果的方法eatApple(int number),以及获取苹果总数的方法getApple(),将该方法设定在public下,这样eatApple(int number)、getApple()方法就暴露了出来,即对外的接口。然后设置Peopel类的私有成员(private)苹果的数量total。
新建一个10_fengzhuang目录,其下新建一个10_fengzhuang.cpp文件,代码如下:
#include <iostream>
#include <string>
using namespace std;
class People
{
private:
int total;
public:
string name;
People(int i = 0)
{
total = i;
}
void eatApple(int cnt){
total = total + cnt;
}
int getApple(){
return total;
}
};
int main()
{
People people;
people.name = "小芳";
people.eatApple(1);
people.eatApple(2);
cout << people.name << "吃的苹果总数:" << people.getApple() << endl;
}
程序中,在People类的构造函数中初始化了total为0,一般都是在构造函数中做初始化,而非在类内直接赋初值,可能会有编译器不支持的情况;程序中其他就没什么好说的了。
编译程序,运行查看结果:
2 数据抽象
数据抽象,指的是只向外界提供关键信息,并隐藏实现细节。数据抽象是一种依赖于接口和实现分离的编程(设计)技术。这么做有什么好处呢?
- 1)类的内部受到保护,不会因无意的用户级错误导致对象状态受损;
- 2)类实现可能随着时间的推移而发生变化,以便应对不断变化的需求,或者应对那些要求不改变用户级代码的错误报告。
举个例子,比如手机可以拍照、听音乐、 收音, 这些都是手机上的功能,用户可以直接使用。 但是拍照的功能是如何实现的,是怎么通过摄像头取像然后怎么在屏幕上显示的过程,作为用户是不需要知道,也不必知道,只需要知道如何拍照即可。
C++ 类为数据抽象提供了可能,它们向外界提供了大量用于操作对象数据的公共方法,也就是说,外界实际上并不清楚类的内部实现。如cout这个对象就是一个公共的接口,我们不必要知道 cout 是如何在屏幕上显示内容的,cout 已经在底层实现好了。
数据封装是一种把数据和操作数据的函数捆绑在一起的机制, 而数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制,比如上面数据封装小节的实例其实也就是个数据抽象的实例,people.eatApple()或people.getApple()也是一个对外的接口。这里就不再单独写例程了,理解了数据抽象这个概念即可。
3 接口(抽象类)
C++中面向对象很多特征都跟Java的太类似了,这个接口也不例外。
接口描述了类的行为和功能,而不需要完成类的特定实现。 C++ 接口是使用抽象类来实现的(抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念)。 如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的。
设计抽象类(通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。因此,如果一个 ABC 的子类需要被实例化,则必须实现每个虚函数,这也意味着 C++ 支
持使用 ABC 声明接口。如果没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。可用于实例化对象的类被称为具体类。
下面举例说明抽象类的用法,这个跟多态有点类似了,只不过多态中使用virtual定义的是虚函数,且虚函数完成了类的特定实现,而抽象类要定义成纯虚函数,纯虚函数不用实现,由派生类重写即可。
新建一个目录 11_abstract,编辑一个 11_abstract.cpp,代码如下:
#include <iostream>
#include <string>
using namespace std;
//动物类
class Animal
{
public:
virtual void speak() = 0;
};
//定义一个People类,继承Animal
class People : public Animal
{
public:
void speak(){
cout << "People的speak()方法" << endl;
}
};
//定义一个Dog类,继承Animal
class Dog : public Animal
{
public:
void speak(){
cout << "Dog的speak()方法" << endl;
}
};
int main()
{
People people;
Dog dog;
people.speak();
dog.speak();
return 0;
}
编译程序,运行结果如下:
输出结果跟https://winter.blog.csdn.net/article/details/129418745结果一样,但要理解的是多态和这个接口是两个不同的思想,前者通过虚函数实现多态的机制,核心就是通过基类访问派生类定义的函数;后者是通过纯虚函数实现的接口机制,目的是为了给其他类提供一个可以继承的适当的基类。
4 总结
本次博文总结数据封装、数据抽象,以及接口, 数据封装是一种把数据和操作数据的函数捆绑在一起的机制, 而数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制,在 C++程序中,任何带有公有和私有成员的类都可以作为数据封装和数据抽象的实例,接口(抽象类)描述了类的行为和功能,而不需要完成类的特定实现。这三个有点绕,写几个实例对比感觉下就知道了。
作于202303091600,已归档
———————————————————————————————————
本文为博主原创文章,未经博主允许不得转载!
若本文对您有帮助,轻抬您发财的小手,关注/评论/点赞/收藏,就是对我最大的支持!
祝君升职加薪,鹏程万里!