1、第二章 类和对象(一),2.1 面向对象方法概述 2.2 类的定义 2.3 类的成员函数 2.4 对象的定义及使用,2.1.1面向对象方法要点,面向对象方法学的出发点和基本原则是,尽可能模拟人类习惯的思维方式,使开发软件的方法与过程尽可能接近人类认识世界解决问题的方法与过程,也就是使描述问题的问题空间(也称为问题域)与实现解法的解空间(也称为求解域)在结构上尽可能一致。 计算机中的实体称为解空间对象; 客观世界中的实体称为问题空间对象;,结构化程序设计的方法是把程序看作是工作在数据上的一系列过程或函数的集合。程序的定律是:程序=算法+数据结构,2.1.1面向对象方法要点,面向对象方法把程序看作
2、是互相协作而又彼此独立的对象的集合。对象间通过发送消息而相互作用。程序的定律是:对象=(算法+数据结构)程序=(对象+对象+),面向对象的方法学可以用下式概括: OO=Objects+Classes+Inheritance+Communication With messages,2.1.1面向对象方法要点,面向对象方法具有下述4个要点:,面向对象的软件系统是由对象(Object)组成的; 把所有对象都划分成各种对象类(简称为类,Class), 每个对象类都定义了一组数据和方法;,按照子类(派生类)与父类(基类)的关系,把若干个对象类组成一个层次结构的系统,这种现象称为继承(Inheritanc
3、e); 对象彼此之间仅能通过传递消息(message)互相联系。,2.1.1面向对象方法要点,基于对象(Object-based)的方法: Objects+Communication With messages 面向对象的方法:OO=Objects+Classes+Inheritance+Communication With messages,2.1.2基本概念-对象,对象具有如下特征: 有一个名字用来唯一的标识该对象; 有一组状态用来描述其特征(属性); 有一组操作用来实现其功能(行为)。,现实世界中的对象: 一切有形事物和抽象概念都是对象。 我们身边发生的一切事件都是对象。 对象可以是人、
4、物、事件、规则、概念等。,2.1.2基本概念-类,类是对具有相同数据和相同操作的一组相似对象的描述,通常在这种描述中也包括对怎样创建该类的新对象的说明。,类名:Circle 状态描述(属性):圆心位置、半径大小、颜色 方法(行为):显示自己放大缩小半径在屏幕上移动位置改变颜色,2.1.2基本概念-实例,定义类是建立对象时使用的“样板”,按照这个样板所建立的一个个具体的对象,就是类的实际的例子,通常称为实例。,学生1 学生2 学生3 学生4 。,学生对象1 学生对象2 学生对象3 学生对象4 。,现实世界,学生类,学生对象,2.1.2基本概念-消息,定义:某个对象提出执行另一个对象具有的某个服务
5、的申请。接受消息的对象主动完成指定服务。,组成: 接收消息的对象; 消息名; 零个或若干个参数。,性质: 同一对象可接收不同形式的多个消息,产生的响应各不相同; 相同形式的消息可以送给不同的对象,产生的响应各不相同; 一个对象可以立即响应发送给它的消息,也可以暂时不响应消息。,分类: 要求返回对象内部属性(状态)的消息; 要求改变对象内部属性(状态)的消息; 要求改变系统状态的消息,或产生特定结果的消息。,2.1.2基本概念-消息,2.1.2基本概念-方法和属性,方法:就是对象所能执行的操作,即服务。方法描述了对象执行操作的算法,响应消息的方法。在C+中称为成员函数。,属性:就是类中所定义的数
6、据,它是对客观世界实体所具有性质的抽象。C+中称为数据成员。,2.1.3基本特征封装性,定义:封装性就是信息隐藏,把对象的实现细节对外界隐藏起来了。,一个对象就像是一个黑盒子,表示对象状态的属性和服务的实现代码被封装放在黑盒子里,从外面无法看见,更不能进行修改。对象向外界提供访问的接口,外界只能通过对象的接口来访问该对象。,2.1.3基本特征继承性,继承就是指能够直接获得已有的性质或特征,而不必重复定义它们。在面向对象的软件技术中,继承是子类自动地共享基类中定义的数据和方法的机制。,自然世界中的继承关系,2.1.3基本特征继承性,当一个类只有一个父类时,为单重继承;有多个父类时,为多重继承;,
7、继承性使得用户开发新的应用系统时不必完全从零开始; 继承机制还使得我们可以将与现实生活空间相一致的思维方式应用于程序空间。,2.1.3基本特征多态性,多态性多态是指一个名字有多种语义,或一个相同界面有多种实现;或是指发出同样的消息被不同类型的对象接受而导致完全不同的行为。即对象根据所接收到的消息做出相应的操作。,例:在学籍管理系统中,学生类(基类) 计算成绩的操作,中学生类(派生类) 计算成绩的操作,大学生类(派生类) 计算成绩的操作,2.1.3基本特征多态性,函数重载和运算符重载表现了最简单的多态性。 函数重载:void f(int,int,char);void f(char,float);
8、void f(int,int);void f(int,float);,2.1.3基本特征多态性,又如:在绘图系统中使用的多态性。,运算符重载:例如,为运算符+ 、- 、 * 、/ 等赋以新的含义,以实现类对象的运算。,2.1.3基本特征多态性,运行时的动态性(动态联编):运行时才才具体确定对象所属类层次中的具体类,从而确定外部程序所发消息的匹配对象和匹配方法。,编译时的动态性(静态联编):编译时确定消息的具体操作对象。,2.1.3面向对象方法的基本特征,封装性、继承性、多态性是构成面向对象程序设计的三大特征。,封装性是基础继承性是关键多态性是补充,2.2类的定义,类是把各种不同类型的数据(称为
9、数据成员)和对数据的操作(称为成员函数)组织在一起而形成的用户自定义的数据类型。,C+中,类定义包括类说明和类实现两大部分。 说明部分提供了对该类所有数据成员和成员函数的描述; 实现部分则提供了所有成员函数的实现代码。,2.2.1类定义的一般形式:,class 类名 public:数据成员或成员函数 private:数据成员或成员函数 protected:数据成员或成员函数 ;,类的定义,类的设计是以数据为中心,还是以行为为中心?,主张“以行为为中心”的人关注类应该提供什么样的服务和接口,他们习惯上将public 类型的函数写在前面,而将private 类型的数据写在后面。,主张“以数据为中心
10、”的人关注类的内部数据结构,他们习惯上将private 类型的数据写在前面,而将public 类型的函数写在后面。,类的定义,坚持并且建议在设计类时“以行为为中心”,即首先考虑类应该提供什么样的函数。,class A private:int i,j;float x,y; public:void Func1(void);void Func2(void);. ;,class A public:void Func1(void);void Func2(void); private:int i,j;float x,y;. ;,例2-1 学生类的设计,class Student public:void d
11、isplay()cout“num:“numendl;cout“name:“nameendl;cout“sex:“sexendl;void setvalue(int xh,string xm,char xb)no=xh;name=xm;sex=xb; private:int num;string name;char sex; ;,2.3.1类的成员函数-成员函数的定义,成员函数的定义通常采用两种方式。 第1种:将成员函数定义在类的内部。此时,被默认为内联函数。,第2种:在类定义中只给出成员函数的原型,而成员函数的定义放在类的外部。,函数返回类型 类名:成员函数名(形式参数表) /函数体 ,/st
12、udent.h这是头文件,在此文件对类进行声明 #include #include using namespace std;class Student public:void display();void setvalue(int,string,char); private:int num;string name;char sex; ;,例2-2 在类外定义成员函数,例2-2 在类外定义成员函数,/student.cpp 这是类的实现文件 #include “student.h“ void Student:display() cout“num:“numendl; cout“name:“name
13、endl; cout“sex:“sexendl; void Student:setvalue(int xh,string xm,char xb) no=xh;name=xm;sex=xb; ,练习 CTime类的设计,定义一个时间类Ctime,能提供设置由时、分、秒组成的时间。,如果一个类的成员函数仅读取对象的属性,可以将其定义成const类型的函数。这样做的优点是让使用者明确地知道该函数不修改对象的值,也起到了对对象的保护作用。,2.3.2类的成员函数-常成员函数,常成员函数的说明格式如下:类型 函数名(参数表) const;,简单地说,const成员函数与普通成员函数的唯一区别是const
14、成员函数不会直接或间接地修改类的属性。,class Point public:int getx() const;/在函数头之后注明constint gety() const;void display( ) const;.private:int x, y; int Point:getx() const /此处的const也是必要的 return x; ,例2-3 常成员函数,2.3.2类的成员函数-常成员函数,与inline不同的是,const必须在成员函数声明和实现时都指明,即const属于函数原型的一部分而不仅是修饰词。 程序中可以定义常量对象(与普通常量具有相同含义),如:const Po
15、int pt; 通过常量对象pt只能调用类的const方法。,例2-4 重载成员函数,#include using namespace std; class myclass public: void set()x=10;y=20;z=30;void set(int xx)x=10;y=20;z=30; void set(int xx,int yy )x=xx;y=yy;z=30;void set(int xx,int yy ,int zz) x=xx;y=yy;z=zz;void print()cout xt yt zn; private: int x;int y;int z; ;,int m
16、ain() myclass b1; cout “x y zn“; b1.set ();b1.print ();b1.set (11);b1.print ();b1.set (11,22);b1.print ();b1.set (11,22,33);b1.print ();return 0; ,例2-4重载成员函数,例2-5带默认参数值的成员函数,计算盒子的体积。,#include using namespace std; class Box public:int get_volume(int length,int width = 2,int height = 3); private:int l
17、ength;int width; int height; ;,例2-5带默认参数值的成员函数,int Box:get_volume(int l, int w, int h) length = l; width = w; height = h; cout lengtht widtht heightt; return length*width*height; ,例2-5带默认参数值的成员函数,int main() Box b1; int x = 6, y = 8, z = 10; cout “Length Width Height Volumen“; cout b1.get_volume(x, y
18、, z) “n“; cout b1.get_volume(x, y) “n“; cout b1.get_volume(x) “n“; cout b1.get_volume(x, 9) “n“; cout b1.get_volume(6, 6, 6) “n“; return 0; ,类的成员函数设计原则,一般采用成员函数设计成类外实现的函数。 当成员函数的某个参数在函数体内不会或不应该被修改时,用const关键字修饰。 当成员函数只能读取类中成员变量,但不能修改时,用const修饰该成员函数。 成员函数的输出型参数,应设计成引用类型。,2.4对象的定义及使用,对象定义的一般格式如下: 类名 对象
19、名1,对象名2,对象名n; 例如:Point a,b; 指向对象的指针变量定义格式如下: 类名 *指针变量名1,*指针变量名2;,对象中成员的访问,访问对象的成员 访问对象的数据成员 调用它的成员函数,访问对象的成员,访问对象的数据成员 对象名.数据成员名 指针变量名-数据成员名 (*指针变量名).数据成员名,访问对象的成员函数 对象名.成员函数名(实参表) 指针变量名-成员函数名(实参表) (*指针变量名).成员函数名(实参表),例2-6访问对象的成员,#include #include #include “student.h“ using namespace std; int main()
20、 Student s1,*ps1,s2;s1.setvalue(101,”zhang”,f);s2.setvalue(102,”wang”,m);s1.display();s2.display();ps1= ,指向当前对象的this指针,一个类的所有对象调用的成员函数都是同一代码段。那么,成员函数又是怎么识别no,name和sex是属于哪一个对象的呢?,原来,在调用s1.setvalue(101,”zhang”,f);时,成员函数除了接受3个实参外,还接受到了对象s1的地址。这个地址被一个隐含的形参指针this所获取,等同于执行this=&s1。所有对数据成员的访问都被隐含地加上前缀this-。,指向当前对象的this指针,void Student:set_value(int xh,string xm,char xb) this-no=xh;this-name=xm;this-sex=xb; ,因此,Student类的setvalue()成员函数和display()成员函数还可以表示成下列代码:,void Student:display() coutnumnamesexendl; ,练习,定义Ctime类,编制相应的函数来测试类的功能。,