一、对象的概念
是系统中用来描述客观事物的一个实体,它是用来构成系统的一个基本单位。对象由一组属性和一组行为构成。
属性:用来描述对象静态特征的数据项。
行为:用来描述对象动态特征的操作序列。
对象名 | 属 性 | 方法 (操作) | 对象名 | 属 性 | 方法 (操作) | … |
张三 | 性别:男 年龄:21 学历:本科 专业: 计算机 | 吃饭 上课 实验 锻练 … | 李四 | 性别:女 年龄:20 学历:本科 专业: 计算机 | 吃饭 上课 实验 锻练 … | … |
对象是现实世界中的一个客观实体,其特性是:
>每一个对象都有一个名字;
>用属性(或称状态)描述对象的某些特征;
>通过一组操作来描述对象的各种行为。
总结:
1.类是一组相关的属性(变量)和行为(方法)的集合。是由一个抽象概念设计的产物。
2.对象是由一个类型实例化后的具体表现形式。就具体存在的实体。
3.成员变量是对象的属性(可以是变量,指针,数组等),属性的值确定对象的状态。
4.成员函数是对象的方法,确定对象的行为。
状态和行为是对象的主要属性。
1.对象的状态又称为对象的静态属性,主要指对象内部所包含的各种信息,也就是变量。每个对象个体都有自己专有的内部变量,这些变量的值标明了对象所处的状态。
2.对象的方法(行为)一方面把对象的内部变量包裹,封装,保护起来,使得只有对象自己的方法才能操作这些内部变量,另一方面,对象的方法还是对象与外部环境和其他对象交互,通信的接口,对象的环境和其他对象可以通过这个接口来调用对象的方法,操纵对象的行为和改变对象的状态。
对象是现实世界的实体或概念在计算机逻辑中的抽象表示。具体地,对象是具有唯一对象名和固定对外界接口的一组属性和操作的集合,用来模拟或影响现实世界问题的一个或一组因素。
面向对象的程序设计的优点:
1.对象的数据封装特性彻底消除了传统结构方法中数据与操作分离所带来的种种问题,提高了程序的可复性和可维护性,降低了程序员保持数据与操作相容的负担。
⒉.对象的数据封装特性还可以把对象的私有数据和公共数据分离开,保护了私有数据,减少了可能的模块间干扰,达到降低程序复杂性,提高可控性的目的。
3.对象作为独立的整体具有良好的自恰性,即它可以通过自身定义的操作来管理自己。一个对象的操作可以完成两类功能,一是修改自身的状态,二是向外界发布消息。
4.在具有自恰性的同时,对象通过一定的接口和相应的消息机制与外界联系。这个特性与对象的封装性结合在一起,较好地实现了信息的隐藏。
5.通过继承可以很方便地实现应用的扩展和已有代码的重复使用。总结:面向对象程序设计是将数据及数据的操作封装在一起,成为一个不可分割的整体,同时将具有相同特性的实体抽象成为一种新的数据类型----类。通过对象间的消息传递是整个系统运转。
二、类的概念
忽略事物的非本质特征,只注意那些与当前目标有关的本质特征,从而找出事物的共性,把具有共同性质的事物划分为一类,得出一个抽象的概念。
面向对象方法中的“类”
1>具有相同属性和行为的一组对象进行抽象得到的集合。
2>为属于该类的全部对象提供了抽象的描述,包括属性和行为两个主要部分。
类与对象的关系:
如模具与铸件之间的关系,一个属于某类的对象称为该类的一个实例.
如 对象“张三”、“李四”、……具有相同的一些属性,操作,将其抽象具体所描述的数据,可抽象为一个类别——类:即学生类
类是对象的抽象
对象是类的实例,类的具体化
类是创建对象的样板,它包含对创建对象的状态描述及操作行为的说明;
对象是类的实例化(对象变量、对象数组等)。
类是具有相同性质和功能的对象的抽象。
类是抽象的概念,而对象是具体的,类只是一种数据类型,而对象是属于该类的一个变量,占用一定的存储单元。
::作用域运算符,用它来指明哪个函数或数据属于哪一个类,使用类中成员的全名:
类名::成员名
三、面向对象系统的最突出的特征:
封装性、继承性、多态性
1>数据的抽象与封装
1.数据的抽象:是对数据进行实例分析,抽取其共同性质的结果。
如:“学生“对象,先对一些学生实例进行分析,确定他们的共同特性或主要特性(姓名、性别、年龄、专业等)忽略不同点或次要的引不起兴趣的那些特性(长相差异、性格差异等)。
2.数据的封装
将数据结构以及作用于数据结构上的操作组成一个实体,把数据的表示方式及操作细节隐藏起来,用户通过接口对数据进行操作。
这样,用户就只知道操作接口对该数据进行操作,而不知道内部是如何做的以及如何表示的一数据的封装。
2>数据的继承
定义:特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。
1.通过继承可实现和增强代码的可重用性,是面向对象技术能够提高软件开发效率的重要原因之一。
2.在创建新的派生类时,只要指明了派生类是由哪个基类派生的便可自动继承基类的属性和方法。
3.修改或扩充程序功能时不必修改原代码(增加新代码即可)。
3>数据的多态
定义:指在一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在一般类及其各个特殊类中具有不同的语义。
如:数的加法:实数的加法
复数的加法
如: max()函数的调用:(函数重载)
max(a,b)——求二个数之间的最大数;
max(a,b.c)——求三个数之间的最大数;
四、类和对象的关系
C++的类是在C语言的结构体的基础上扩充而来的。在C++中,对象的类型称为类,类是对象的抽象,代表了一批对象的共性和特征,对象是类的具体实例。
类的基本结构
1.名称/标记
2.类的数据成员(类的组成)
3.类的成员函数(类的动作、行为)
对象:一个类的变量是一个类的实例,被称为对象。
结构体和类
结构体中数据与操作分离 | 类中数据与操作封装在一起 |
struct student { int number; char name[15]; float score; }; | struct student { int number; char name[15]; float score; void display( )//函数成员 { cout<<”number: ”<< number; cout<<”name: ”<< name; cout<<”score: ”<< score <<endl; } }; |
void display(Student * stu) { printf(”number:%d”,stu->number); printf(”name:%s”,stu->name); printf(”score:%f\n”,stu->score); } |
在结构体中,未被指明为公有成员还是私有成员的成员,默认为公有成员。
在类中,但凡是未定义为公有成员(public)或保护成员(protected)的成员均为私有成员(private) —— 封装性的体现。
对象的关系
1、包含:当对象A是对象B的属性时,称对象B包含对象A。
2、继承:当对象A是对象B的特例时,称对象A继承对象B。
3、关联:当对象A的引用是对象B的属性时,称对象A和对象B之间是关联关系。所谓对象的引用是指对象的名称,地址,句柄等可以获得和操纵该对象的途径。
五、类的类型
用户自定义的数据类型。如果程序中要使用类类型 , 必须根据实际需要设计,或者使用已设计好的类。
C++定义一个类,其方法与定义一个结构体类型是相似的,
一般形式为:
class 类名
{
成员列表
};
说明
1.类定义时必须给出各个数据成员的数据类型声明。
2.定义类时,计算机并不给数据成员分配内存空间,在定义对象时才分配空间;
3.不能在定义时给类中的成员赋初值。
4.数据成员既可以是基本数据类型,也可以是复杂数据类型(数组、指针、引用、结构体,也可以是类变量等)。
成员的访问
无论数据成员还是函数成员,类的每个成员都有访问控制属性,可以使用成员访问限定符说明:
●public (公有的)
●private (私有的)
●protected (保护的)
成员访问限定符
1)公有成员:public ——所定义的成员是开放的,可在任何地方访问(类内部及程序的其他地方)
public实现了类的外部接口。
2)私有成员:private——所定义的成员是隐藏的,只能在类内部访问,不能在程序的其他地方访问;
private实现了私有成员的隐蔽。
3)保护成员: protected——所定义的成员是半开放的,可在类内部访问,也可在其派生类中访问,但不能在程序的其他部分访问。
如果在类体起始点无访问说明符,系统默认定义为私有( private )。访问说明符private (私有的)和protected(保护的)体现了类具有封装性(Encapsulation).
成员访问控制是C++的类和结构体又一个重要特性。
加上访问标号,类定义更一般的形式为:
class 类名
{ public :
数据成员或成员函数
protected:
数据成员或成员函数
private :
数据成员或成员函数
};
说明:
类的定义中,private、protected、public可以按任意顺序出现任意次;但通常private放在前面,protected放在中间,public放在最后面。
实际编程中,为了使程序清晰,每一种成员访问限定符在类体中只出现一次,通常是将相同访问控制属性的成员集中在一起来写。
类中的数据成员通常说明为私有成员,以实现数据的隐藏;而成员函数通常设为公有的,以通过消息传递访问数据成员,保护成员主要用于继承。
class student
{ private:
int number;
char name[15];
float score;
public:
void display( )
{ cout<<”number: ”<< number;
cout<<”name: ”<< name;
cout<<”score: ”<< score <<endl;
}
};
类中引进了成员函数(member function)或函数成员:也就是函数也成了数据(类)中的一员。类把数据(事物的属性)和函数(事物的行为--操作)封装为一个整体。
四个数据成员被说明成私有,而六个函数成员被说明成公有;这就是说如果从外部对四个数据成员进行操作的话.只能通过六个公有函数来完成,数据受到了良好的保护,不易受副作用的影响。公有函数集定义了类的接口(interface).
类是一种数据类型,定义时系统不为类分配存储空间,所以不能对类的数据成员初始化。类中的任何数据成员也不能使用关键字extern、auto 或register限定其存储类型。
成员函数可以直接使用类定义中的任一成员,可以处理数据成员,也可调用函数成员。
成员函数的定义:
前面只对成员函数作了一个声明(函数的原型),并没有对函数进行定义。
函数定义通常在类的说明之后进行,其格式如下:
回值类型类名::函数名(参数表)
{········}/函数体
其中运算符" :: "称为作用域解析运算符(scope resolution operator),它指出该函数是属于哪一个类的成员函数。
六、定义对象的方法
对象是类的实例(instance)。声明一种数据类型只是告诉编译系统该数据类型的构造,并没有预定内存。类只是一个样板(图纸),以此样板可以在内存中开辟出同样结构的实例——对象。
定义一个类时,也就是定义了一个具体的数据类型。若要使用类,需要将类实例化,即定义该类的对象。
对象的定义:
1. 在声明(定义)类的同时定义对象
2. 先声明(定义)类再定义对象
3. 不出现类名,直接定义对象
1>在声明(定义)类的同时定义对象
class student
{ private:
int number;
char name[15];
float score;
public:
void display( ) //函数成员
{ cout<<”number: ”<< number;
cout<<”name: ”<< name;
cout<<”score: ”<< score <<endl;
}
} stu1, stu2;
2>先声明(定义)类再定义对象
如:class student stu;
3>不出现类名,直接定义对象
class
{ private:
int number;
char name[15];
float score;
public:
void display( ) //函数成员
{ cout<<”number: ”<< number;
cout<<”name: ”<< name;
cout<<”score: ”<< score <<endl;
}
} stu1,stu2;
七、类的成员函数
类的成员函数可以访问本类中任何成员。
在类中引进了成员函数(member function)或函数成员,也就是函数也成了数据(类)中的一员。类把数据(事物的属性)和函数(事物的行为,操作)封装为一个整体。
若四个数据成员被说明成私有,而六个函数成员被说明成公有,这就是说如果从外部对四个数据成员进行操作的话.只能通过六个公有函数来完成,数据受到了良好的保护,不易受副作用的影响。公有函数集定义了类的接口(interface).
类是一种数据类型,定义时系统不为类分配存储空间,所以不能对类的数据成员初始化。类中的任何数据成员也不能使用关键字extern、auto 或register限定其存储类型。
成员函数可以直接使用类定义中的任一成员,可以处理数据成员,也可调用函数成员。成员函数的定义:
前面只对成员函数作了一个声明(函数的原型),并没有对函数进行定义。
函数定义通常在类的说明之后进行,其格式如下:
回值类型类名::函数名(参数表)
{···}//函数体
其中运算符"::"称为作用域解析运算符(scope resolution operator),它指出该函数是属于哪一个类的成员函数。
面向对象程序设计一般将数据隐蔽起来,外部不能直接访问,而把成员函数作为对外界的接口,通过成员函数访问数据。即数据成员是属性,成员函数是方法,通过方法存取属性。
1. 在类中定义(也是声明)成员函数。
2. 成员函数的声明在类中,定义在类外部
1> 在类中定义(也是声明)成员函数,形式为:
class 类名
{ •••
返回类型 函数名(形式参数列表)
{
函数体
}
•••
} ;
class student
{ private:
int number;
char name[15];
float score;
public:
void display( ) //成员函数定义
{ cout<<”number: ”<< number;
cout<<”name: ”<< name;
cout<<”score: ”<< score <<endl;
}
} ;
2> 成员函数的声明在类中,定义在类外部,形式为:
class 类名
{ •••
返回类型 函数名(类型1参数名1,类型2参数名
返回类型 函数名(类型1,类型2,...);
•••
};
返回类型 类名 :: 函数名(形式参数列表)
{ 函数体
}
class student
{ private:
int number;
char name[15];
float score;
public:
void display( ); //成员函数声明
} stu1,stu2;
void student :: display( ) //成员函数定义
{ cout<<”number: ”<< number;
cout<<”name: ”<< name;
cout<<”score: ”<< score <<endl;
}
类的成员函数原型声明必须出现在成员函数定义之前,否则编译会出错。
在类的内部声明成员函数,而在类的外部定义成员函数,这 是一个良好的编程习惯。因为不仅可以减少类体的长度,使类体结构清晰,便于阅读,而且有助于类的接口和实现分离。
1.内置成员函数
类的成员函数可以指定为inline,即内置成员函数。
默认情况下,在类体中定义的成员函数若不包括循环等控制结构,符合内置函数要求时,C++会自动将它们作为内置函数处理(隐式inline) 。
如果成员函数在内体外定义,须显式地将成员函数声明为inline。显示定义是指在定义内置函数时,仍将函数放在类定义体之外,但为了使之能起到内置函数的作用,在函数定义前加上inline.
class student
{ private:
int number;
char name[15];
float score;
public:
inline void display( );
} stu1,stu2;
inline void student :: display( )
{ cout<<”number: ”<< number;
cout<<”name: ”<< name;
cout<<”score: ”<< score <<endl;
}
2.成员函数的存储方式
C++会为每个对象的数据成员分配各自独立的存储空间,像结构体成员那样。
成员函数代码只有公用的一段存储空间,调用不同对象的成员函数时都是执行同一段函数代码。
八、怎样访问对象的成员
1>通过对象名访问对象中的成员
2>通过对象指针访问对象中的成员
3>通过对象引用访问对象中的成员
一、通过成员运算符访问: .
1. 数据成员的使用
格式:对象名 . 成员名
2. 成员函数的使用
格式:对象名 . 成员函数名(实参表)
或:对象名 . 类名 :: 成员函数名(实参表)
或 (*p). 成员名
调用对象中成员函数的一般形式为:
对象指针名一>成员函数名(实参列表)
或 (*p). 成员函数名(实参列表)
#include<iostream>
using namespace std;
class time
{
public:
int hour;
int minute;
int sec;
};
int main()
{
time t1;
time *p = &t1;
cin >> p->hour >> p->minute >> p->sec;
cout << p->hour << ":" << p->minute << ":" << p->sec << endl;
cin >> (*p).hour >> (*p).minute >> (*p).sec;
cout << (*p).hour << ":" << (*p).minute << ":" << (*p).sec << endl;
return 0;
三、通过对象成员的引用访问对象中的成员
访问对象中数据成员的一般形式为:
对象引用变量名 . 成员名
调用对象中成员函数的一般形式为:
对象引用变量名 . 成员函数名(实参列表)
#include<iostream>
using namespace std;
class time
{ public:
int hour;
int minute;
int sec;
} ;
int main( )
{ time t1;
time &t2=t1;
cin>>t2.hour>>t2.minute>>t2.sec;
cout<<t2.hour<<”:”<<t2.minute<<”:”<<t2.sec<<endl;
return 0;
}
如果一个类同时定义了两个或多个对象,则这些同类的对象之间可以互相赋值。
对象名1 = 对象名2(将右边的值逐一赋值给左边的对象)
九、类的封装和信息的隐蔽
1>公用接口与私有实现的分离
公用成员函数是用户使用类的公用接口,即类的对外接口。
通过成员函数对数据成员进行操作称为类的功能的实现,类中被操作的数据是私有的,类的功能的实现细节是隐蔽的,这种实现称为私有实现。类的公用接口与私有实现的分离就形成了信息隐蔽,用户接触到的是公用接口,而不能接触被隐蔽的数据和实现细节。
接口与实现的分离是软件工程的最基本的原则,信息隐蔽是软件工程一个很重要的概念。
优点:
如果想修改或扩充类的功能,只需修改该类中有关的数据成员和与它有关的成员函数,程序中类以外的部分可以不必修改。
如果在编译时发现类中的数据读写有错,不必检查整个程序,只需检查本类中的访问这些数据的成员函数。
如果一个类被多个程序使用,在面向对象程序开发中,往往把类的声明(包含成员函数的声明)放在头文件中。
在程序中用#include把有关类声明头文件包含到程序中。
实际上,一个c++程序是由三个部分组成的:
1.类声明头文件:后缀.h或无后缀
2.类实现文件:后缀为.cpp,类成员函数的定义
3.类的使用文件:主文件