C++ 类 (02)

来源:互联网 发布:阿里云cdn接口php 编辑:程序博客网 时间:2024/06/06 19:58

数据抽象与封装

数据抽象

类的基本思想就是数据抽象封装
数据抽象是一种依赖于接口和实现分离的编程、设计技术。类的设计者必须关心类是如何实现的,但是使用该类的程序开发人员不需要了解这些实现的具体细节。相反而言,使用一个类的程序员仅仅需要了解这个类型的接口能够完成什么工作?能够完成什么功能?而无需具体了解这个类型是如何工作的。
类设计者:
        class Person{        public:        Person();        string name;        int age;        string getName() const;        };
类的使用者:
        //使用类之前必须创建类的实例对象        Person *person = new Person();        //使用这个实例对象来调用这个接口        cout << person->getName();

这样类的设计与使用就形成了分离。

在大型软件、大型的系统的开发中,数据抽象是一种重要的概念。

封装

封装是一项低层次的元素组合起来形成新的、高层次的实体技术。类的设计者讲一个类型的数据成员、函数成员、类类型的成员封装到一起,形成一种新的抽象类型或者具体类型。函数(类外称接口)是封装的一种形式:函数所执行的细节被封装在函数这个本身的实体中。被封装的元素隐藏了他们的实现细节——可以调用但是不能访问他所执行的具体细节,实现的具体语句。

类是一个封装的实体。并且隐藏了实现该类类型的成员。

在C++中,标准库类型有很多封装好的类型如:vector、list、map、set等,这些类型同时兼具有数据抽象与封装的特性,对于类的使用者而言,他是抽象的,因为使用者只需要考虑类接口能够帮助他们完成什么功能?不同的接口能够执行什么动作?并且也是封装的,因为我们无法了解该类型是如何具体实现的,实现的细节是什么?如:
//初始化类vectorint ages[] = {20, 23, 29, 30};vector<int> vAge(ages, ages+3);//使用者只需要了解类接口能够完成什么事情//vector类型的front()返回类型vector中的第一个元素std::cout << vAge.front();//at(index)接口返回类型中第index个元素std::cout << vAge.at(1);

数据抽象与封装的实施手段——访问权限标号

在C++中,使用访问权限标号来定义类的抽象数据接口和实施封装。

一个类可以没有访问权限标号(C++中,class的默认访问权限标号是private,而struct类型的默认访问权限标号是public),也可以包含多个访问权限标号。
如:
//设计了一个类Person,拥有一个接口返回Person的名字class Person{public:Person();private:string name;protected:int age;public:string getName() const;};string Person::getName() const{return name;}Person::Person():name("Josin"), age(22){}

关于访问权限标号public、protected、private的作用范围见我的上一篇博文。


类的具体类型抽象类型

具体类型是类的设计者在设计类的同时也进行了类的接口的实现,抽象类型是指类的设计者只进行了接口的定义而没有进行接口的实现。
如:
class Cooker{public://接口一void cook();//接口二void gruel();//接口三void soup();};

具体类型:
class Cooker{public://接口一void cook(){for (int i = 0; i < 10; i++){std::cout << i << std::endl;}}//接口二void gruel(){int i = 0;while (true){if (i = 100){return;}std::cout << i << std::endl;}}//接口三void soup(int i){if (i == 1000){return;}soup(i+1);}};

抽象类型与具体类型:抽象类型的作用是什么?在日常的软件开发中,时常会碰到一些问题如:不同品牌的电吹风都有一些相似的功能、不同品牌的电饭锅都有一些相似的功能。这里这些”相似的“就是我们抽象类型的作用了,比如说:我们可以在我们的程序中定义一个抽象类型Cooker如上所示,并且定义两个具体类型:Media、Philip来形容两中具体的电饭锅:
class Media : public Cooker{public:void cook(){//执行各自的煮饭功能}void gruel(){//执行各自的熬粥功能}void soup(){//执行各自的熬汤功能}};class Philip : public Cooker{public:void cook(){//执行Philips的煮饭功能}void gruel(){//执行各自的熬粥功能}void soup(){//执行各自的熬汤功能}};

因为不同的品牌具体的煮饭、熬汤的过程有不同,所以只要针对不同的品牌设置不同的步骤就可以了。

数据抽象与封装的好处

  1. 避免类内部出现无意的、可能破坏对象状态的使用者错误。
  2. 随时间的推移可以根据需要改变或者通过用户提交的Bug来完善类的接口实现,而无需改变使用者代码。





































































0 1