《第08章 类和对象课件.ppt》由会员分享,可在线阅读,更多相关《第08章 类和对象课件.ppt(65页珍藏版)》请在三一办公上搜索。
1、第8章 类和对象,C+程序设计,Logo,本章内容,8.1 面向对象程序设计方法概述8.2 类的声明和对象的定义8.3 类的成员函数8.4 对象成员的引用8.5 类和对象的简单应用举例8.6 类的封装性和信息隐蔽,Logo,8.1 面向对象程序设计方法概述,面向对象程序设计:把同一对象的数据和操作封装在一起,使用对象、类、继承、封装、消息等基本概念来进行的程序设计。例如:人们生产汽车时,发动机、底盘、车身和轮子分别由不同生产厂商设计和制造,最后由汽车制造商组装在一起。在组装时,各部分之间有一定的联系,以便协调工作,各部分内部如何工作一无所知。为了进一步说明问题,下面先讨论几个有关的概念。,OO
2、=对象+类+消息+继承+封装+多态,Logo,8.1 面向对象程序设计方法概述,1.对象 对象是具有明显边界和含义的概念、抽象或事物,一个对象代表了一个现实的或虚拟的实体。,自然实体概念实体软件实体,化学过程,Logo,8.1 面向对象程序设计方法概述,1.对象对象(Object)是包含客观世界物体特征的抽象实体,客观世界中任何一个事物都可以看成一个对象。对象可大可小。对象是构成系统的基本单位。对象由属性(Attribute)和行为(Action)两部分组成。对象的两个要素:属性和行为。属性:对象的特征,定义成员变量描述。行为:对象的动作,定义成员函数完成。,Logo,8.1 面向对象程序设计
3、方法概述,对象属性举例:一个学生对象属性:姓名、号码、性别、职业、年级。一个教师对象属性:姓名、号码、性别、职业、职务。一台录像机对象属性:型号、品牌、体积、重量、价格。一台笔记本电脑对象的属性:?,Logo,8.1 面向对象程序设计方法概述,对象行为举例:一个学生对象行为:听课、交作业、考试。一个教师对象行为:讲课、改作业、监考。一台录像机对象行为:录像、播放、暂停、快进、停止。一台笔记本电脑的行为:?,Logo,8.1 面向对象程序设计方法概述,在一个系统中的多个对象之间通过一定的渠道相互联系,如图8.1示意。要使某一个对象实现某一种行为(即操作),应当向它传送相应的消息。对象之间就是这样
4、通过发送和接收消息互相联系的。,Logo,8.1 面向对象程序设计方法概述,2、类 每一个实体都是对象。有一些对象是具有相同的结构和行为的。每个对象都属于一个特定的类型。类(Class)是一组具有相同结构和行为的对象的集合。,Logo,8.1 面向对象程序设计方法概述,2、类类的举例:学生类、教师类、录像机、笔记本电脑、汽车、饮料、气体、矿石、人、动物.,如:10个不同尺寸的三角形是10个对象。这10个三角形对象有相同的属性结构和行为,可以将它们抽象为一种类型,称为三角形类型。,Logo,8.1 面向对象程序设计方法概述,3.封装与信息隐蔽封装:将有关的数据和操作代码封装在一个对象中,形成一个
5、基本单位,各个对象之间相对独立,互不干扰。信息隐蔽:将对象中某些部分对外隐蔽,即隐蔽其内部细节,只留少量接口,以便与外界联系,接收外界的消息。信息隐蔽有利于数据安全,防止无关的人了解和修改数据。,封装可以降低复杂度和出错的可能性,提高类或模块的可重用性、隐藏性,使用方便,易于维护。,Logo,8.1 面向对象程序设计方法概述,3.封装与信息隐蔽,Logo,8.1 面向对象程序设计方法概述,4.继承与派生 继承是一种由已有的类创建新类的机制。子类从父类继承了共性,又派生出自己的各自的特性。父类-子类(派生类)将门虎子继承,Logo,8.1 面向对象程序设计方法概述,Logo,8.1 面向对象程序
6、设计方法概述,Logo,8.1 面向对象程序设计方法概述,父类别可以被多个子类别继承,子类别也可以是别的类的父类,从而建立类继承的层次结构。,Logo,8.1 面向对象程序设计方法概述,C+提供了继承机制,采用继承的方法可以很方便地利用一个已有的类建立一个新的类。这就是常说的“软件重用”(software reusability)的思想。继承的目的:实现代码重用。派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。,Logo,8.1 面向对象程序设计方法概述,5.多态性由继承而产生的相关的不同的类,其对象对同一消息会作出不同的响应。如:动物都会叫,但不同的
7、动物的叫声不同。如:在Windows环境下,用鼠标双击一个文件对象(这就是向对象传送一个消息),根据文件对象的不同,将做不同的操作。如果是可执行文件,则会执行此程序;如果是文本文件,则启动文本编辑器并打开该文件。,Logo,8.1.2 面向对象程序设计的特点,面向对象程序设计面对的是一个个对象。程序设计者的任务包括两个方面:(1)设计所需的各种类和对象,即决定把哪些数据和操作封装在一起;(2)考虑怎样向有关对象发送消息,以完成所需的任务。这时他如同一个总调度,不断地向各个对象发出命令,让这些对象活动起来(或者说激活这些对象),完成自己职责范围内的工作。各个对象的操作完成了,整体任务也就完成了。
8、显然,对一个大型任务来说,面向对象程序设计方法是十分有效的,它能大大降低程序设计人员的工作难度,减少出错机会。,Logo,8.1.4 面向对象的软件开发,随着软件规模的迅速增大,软件人员面临的问题十分复杂。需要规范整个软件开发过程,明确软件开发过程中每个阶段的任务,在保证前一个阶段工作的正确性的情况下,再进行下一阶段的工作。这就是软件工程学需要研究和解决的问题。,面向对象的软件工程包括以下几个部分:,Logo,8.1.4 面向对象的软件开发,Logo,8.2 类的声明和对象的定义,8.2.1对象和类的关系每一个对象都是某一个类的实例;每一个类在某一时刻都有零个或更多的实例;类是静态的,它们的存
9、在、语义和关系在程序执行前就已经定义好了;对象是动态的,它们在程序执行时可以被创建和删除;类是抽象的,不占用内存,而对象是具体的,占用存储空间。在一开始时弄清对象和类的关系是十分重要的。,Logo,8.2 类的声明和对象的定义,8.2.1对象和类的关系白马非马对象和类 这是中国古代伟大的逻辑学家公孙龙(约公元前320-250年)提出的一个著名的逻辑问题,出自公孙龙子白马论。,类是对象的抽象,而对象是类的具体实例。,Logo,8.2类的声明和对象的定义,8.2.2类的声明 在C+中声明一个类类型和声明一个结构体类型是相似的。以前,定义结构体类型,描述一个对象:struct Student int
10、 num;char name20;char sex;Student stud1,stud2;/定义了两个结构体变量stud1和stud2,我们把一个对象可能具有的动作,加入到对象的描述中,就形成了类。,Logo,8.2.2 类的声明,class Student/以class开头 int num;char name20;char sex;/以上3行是数据成员 void display()/这是成员函数coutnum:numendl;coutname:nameendl;coutsex:sexendl;/以上4行是函数中的操作语句;Student stud1,stud2;/定义了两个Student
11、类的对象stud1和stud2 可以看到声明类的方法是由声明结构体类型的方法发展而来的。,Logo,8.2.2 类的声明,class private:/私有成员,缺省存取权限 public:/公有成员 protected:/保护成员;,Logo,8.2.2 类的声明,类一经定义就形成了边界,达成了封装,就像建 了一幢房子访问修饰符的作用就是在房子上开窗,开门,让 别人可以访问。,访问修饰符,Logo,8.2.2 类的声明,访问修饰符,Logo,8.2.2 类的声明,访问修饰符,Logo,8.2.2 类的声明,注意:(1)在声明类类型时,声明为private的成员和声明为public的成员的次序
12、任意,既可以先出现private部分,也可以先出现public部分。(2)如果在类体中既不写关键字private,又不写public,就默认为private。(3)在一个类体中,关键字private和public可以分别出现多次。每个部分的有效范围到出现另一个访问限定符或类体结束时(最后一个右花括号)为止。但是为了使程序清晰,应该养成这样的习惯:使每一种成员访问限定符在类定义体中只出现一次。,Logo,8.2.2 类的声明,可以将上面类Student的声明改为class Student/声明类类型 private:/声明以下部分为私有的int num;char name20;char sex;
13、public:/声明以下部分为公用的void display()coutnum:numendl;coutname:nameendl;coutsex:sexendl;Student stud1,stud2;/定义了两个Student 类的对象,Logo,8.2.2 类的声明,不能把类中的全部成员与外界隔离,一般是把数据隐蔽起来,而把成员函数作为对外界的接口。,Logo,8.2.3 对象的定义,private:id name major fees,public:register,Student类,对象stu1,0521140张三Computer16000register,对象stu1,052224
14、0李四Network16000register,Logo,8.2.3 对象的定义,1.先声明类类型,然后再定义对象声明了类类型后,定义对象有两种形式。(1)class 类名 对象名 class Student stud1,stud2;把class和Student合起来作为一个类名,用来定义对象。(2)类名 对象名 Student stud1,stud2;直接用类名定义对象。这两种方法是等效的。,Logo,8.2.3 对象的定义,class Studentprivate:int id;char name20;char major20;float fees;public:void register
15、()cin id name major fees;Student stu1,stu2;,Logo,8.2.3 对象的定义,2.在声明类类型的同时定义对象class Studentprivate:int id;char name20;char major20;float fees;public:void register()cin id name major fees;stud1,stud2;/定义了两个Student类的对象在定义Student类的同时,定义了两个Student 类的对象。,Logo,8.2.3 对象的定义,3.不出现类名,直接定义对象class/无类名private:/声明以
16、下部分为私有的.public:/声明以下部分为公用的.stud1,stud2;/定义了两个无类名的类对象这种方法很少用。在实际的程序开发中,一般都采用第1种方法。在定义一个对象时,编译系统会为这个对象分配存储空间,以存放对象中的成员。,Logo,8.3 类的成员函数,8.3.1 成员函数的性质类的成员函数与一般函数的区别只是:它是属于一个类的成员,出现在类体中。可以指定为private、public、protected成员函数可以访问本类中任何成员(包括私有和公用数据和函数成员)。,Logo,8.3 类的成员函数,如何指定类的成员函数为public还是private?(1)一般将需要被外界调用
17、的成员函数指定为public,它们是类的对外接口。(2)不被外界调用的,而只是为本类中的成员函数所调用的函数,应指定为private。这种函数的作用是支持其他函数的操作,是类中其他成员的工具函数,类外用户不能调用这些私有的工具函数。,Logo,8.3.2 在类外定义成员函数,成员函数可以在类体中定义,也可以在类外定义。如果是在类外定义,类体中只写成员函数的声明,具体函数定义而在类的外面进行。如:,class Studentprivate:int id;char name20;char major20;float fees;public:void register();/此处只做成员函数声明;,
18、void Student:register()/成员函数的具体定义cin id name majorfees;,Logo,8.3.2 在类外定义成员函数,注意:类体中定义函数时,不需要在函数名前面加上类名,因为函数属于哪一个类是不言而喻的。成员函数在类外定义时,必须在函数名前面加上类名,予以限定(qualifed),“”是作用域限定符(field qualifier)或称作用域运算符,用它声明函数是属于哪个类的。如果在作用域运算符“”的前面没有类名,或者函数名前面既无类名又无作用域运算符“”,如 display()或 display()则表示display函数不属于任何类,这个函数不是成员函数
19、,而是全局函数,即一般普通函数。,Logo,8.3.2 在类外定义成员函数,注意:类体中作原型声明,然后在类外定义,类体的位置应在函数定义之前,否则编译时会出错。在类的内部对成员函数作声明,而在类体外定义成员函数,这是程序设计的一种良好习惯。,Logo,8.3.4 成员函数的存储方式,用一段空间存放共同的函数代码段,在调用各对象的函数时,都去调用这个公用的函数代码。每个对象占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间。,一个对象所占的空间大小只取决于该对象中数据成员所占的空间,而与成员函数无关。函数代码是存储在对象空间之外的。,#includeusing
20、 namespace std;class Timeint hour;int minute;int sec;public:void set()cin hour minute sec;int main()coutsizeof(Time)endl;return 0;,Logo,8.4 对象成员的引用,在程序中经常需要访问对象中的成员。访问对象中的成员可以有3种方法:通过对象名和成员运算符访问对象中的成员;通过指向对象的指针访问对象中的成员;通过对象的引用变量访问对象中的成员。,Logo,8.4.1 通过对象名和成员运算符访问对象中的成员,访问对象中成员的一般形式:对象名.成员名 不仅可以在类外引用对
21、象的公用数据成员,而且还可以调用对象的公用成员函数,但同样必须指出对象名,如stud1.register();/正确,调用对象stud1的公用成员函数register();/错误,没有指明是哪一个对象的register函数由于没有指明对象名,编译时把register()作为普通函数处理。,Logo,8.4 对象成员的引用,只能访问public成员,而不能访问private成员,如果已定义id为私有数据成员,下面的语句是错误的:stud1.id=10101;/num是私有数据成员,不能被外界引用 在类外只能调用公用的成员函数。在一个类中应当至少有一个公用的成员函数,作为对外的接口,否则就无法对对
22、象进行任何操作。,Logo,8.4.2 通过指向对象的指针访问对象中的成员,如果有以下程序段:class Timepublic:/数据成员是公用的int hour;int minute;Time t,*p;/定义对象t和指针变量pp=/输出p指向的对象中的成员hour在p指向t的前提下,p-hour,(*p).hour和t.hour三者等价。,Logo,8.4.3 通过对象的引用变量来访问对象中的成员,如果已声明了Time类,并有以下定义语句:Time t1;/定义对象t1Time/输出对象t1中的成员hourt2与t1共占同一段存储单元(即t2是t1的别名),因此t2.hour就是t1.ho
23、ur。,Logo,8.5类和对象的简单应用举例,例8.1 最简单的例子。#include using namespace std;class Time public:/数据成员为公用的 int hour;int minute;int sec;int main()Time t1;/定义t1为Time类对象cint1.hour;/输入设定的时间cint1.minute;cint1.sec;coutt1.hour:t1.minute:t1.secendl;return 0;,例8.2 引用多个对象的成员。(1)程序(a),#include using namespace std;class Time
24、public:int hour;int minute;int sec;int main()Time t1;/定义对象t1cint1.hour;cint1.minute;cint1.sec;coutt2.hour;/向t2的数据成员输入数据cint2.minute;cint2.sec;coutt2.hour:t2.minute:t2.secendl;return 0;,例8.2 引用多个对象的成员。(1)程序(a),#include using namespace std;class Timepublic:int hour;int minute;int sec;int main()void se
25、t_time(Time/调用show_time函数,输出t1对象中的数据,Time t2;/定义t2为Time类对象set_time(t2);show_time(t2);return 0;void set_time(Time/输出对象中的数据,例8.3 将例8.2的程序改用含成员函数的类来处理。,#include using namespace std;class Timepublic:void set_time();/公用成员函数void show_time();/公用成员函数private:/数据成员为私有int hour;int minute;int sec;,int main()Tim
26、e t1;/定义对象t1 t1.set_time();/调用对象t1的成员函数set_time,向t1的数据成员输入数据t1.show_time();/调用对象t1的成员函数show_time,输出t1的数据成员的值Time t2;/定义对象t2t2.set_time();t2.show_time();return 0;void Timeset_time()/在类外定义set_time函数 cinhour;cinminute;cinsec;void Timeshow_time()/在类外定义show_time函数 couthour:minute:secendl;,#include using
27、namespace std;class Time void set_time(void);void show_time(void);int hour;int minute;int sec;Time t;int main()set_time();show_time();return 0;int set_time(void)cint.hour;cint.minute;cint.sec;int show_time(void)coutt.hour:t.minute:t.secendl;,P261第1题,P261第2题,P261第3题,Logo,8.6 类的封装性和信息隐蔽,8.6.1 公用接口与私有实
28、现的分离 从前面的介绍已知:C+通过类来实现封装性,把数据和与这些数据有关的操作封装在一个类中,或者说,类的作用是把数据和算法封装在用户声明的抽象数据类型中。在声明了一个类以后,用户主要是通过调用公用的成员函数来实现类提供的功能(例如对数据成员设置值,显示数据成员的值,对数据进行加工等)。因此,公用成员函数是用户使用类的公用接口(public interface),或者说是类的对外接口。,Logo,8.6 类的封装性和信息隐蔽,类中被操作的数据是私有的,实现的细节对用户是隐蔽的,这种实现称为私有实现(private implementation)。这种“类的公用接口与私有实现的分离”形成了信息
29、隐蔽。软件工程的一个最基本的原则就是将接口与实现分离,信息隐蔽是软件工程中一个非常重要的概念。它的好处在于:(1)如果想修改或扩充类的功能,只需修改本类中有关的数据成员和与它有关的成员函数,程序中类外的部分可以不必修改。(2)如果在编译时发现类中的数据读写有错,不必检查整个程序,只需检查本类中访问这些数据的少数成员函数。,Logo,8.6.2 类声明和成员函数定义的分离,在面向对象的程序开发中,一般做法是将类的声明(其中包含成员函数的声明)放在指定的头文件中,用户如果想用该类,只要把有关的头文件包含进来即可,不必在程序中重复书写类的声明,以减少工作量,节省篇幅,提高编程的效率。由于在头文件中包
30、含了类的声明,因此在程序中就可以用该类来定义对象。由于在类体中包含了对成员函数的声明,在程序中就可以调用这些对象的公用成员函数。为了实现信息隐蔽,对类成员函数的定义一般不放在头文件中,而另外放在一个文件中。,Logo,8.6.2 类声明和成员函数定义的分离,例如,可以分别写两个文件:/student.h(这是头文件,在此文件中进行类的声明)class Student/类声明 public:void display();/公用成员函数原型声明private:int num;char name20;char sex;/student.cpp/在此文件中进行函数的定义#include#include
31、 student.h/不要漏写此行,否则编译通不过void Studentdisplay()coutnum:numendl;coutname:nameendl;coutsex:sexendl;,Logo,8.6.2 类声明和成员函数定义的分离,为了组成一个完整的源程序,还应当有包括主函数的源文件:/main.cpp 主函数模块#include#include student.h/将类声明头文件包含进来int main()Student stud;/定义对象 stud.display();/执行stud对象的display函数return 0;这是一个包括3个文件的程序,组成两个文件模块:一个是主模块main.cpp,一个是student.cpp。在主模块中又包含头文件student.h。在预编译时会将头文件student.h中的内容取代#include student.h行。,Logo,8.6.2 类声明和成员函数定义的分离,请注意:由于将头文件student.h放在用户当前目录中,因此在文件名两侧用双撇号包起来(student.h)而不用尖括号(),否则编译时会找不到此文件。,Thank you本章到此结束,
链接地址:https://www.31ppt.com/p-2163186.html