380 likes | 522 Views
3.1 概述 一、 C++ 不仅扩充了 C 面向过程的功能,而且增加了面向 对象的功能。 二、客观世界中任何一个事物都可以看成一个对象。作为对 象它至少应该包含两个因素,一是从事活动的主体,而是活动的 内容。 三、从计算机角度看,一个对象应该包含两个要素,一是数 据,二是需要进行的操作。即,对象是一个包含数据以及与这些 数据有关的操作的集合。 四、传统的面向过程的程序设计围绕功能进行,用一个函数 实现一个功能。 五、面向对象程序设计面对的是一个个的对象。
E N D
3.1 概述 一、C++不仅扩充了C面向过程的功能,而且增加了面向 对象的功能。 二、客观世界中任何一个事物都可以看成一个对象。作为对 象它至少应该包含两个因素,一是从事活动的主体,而是活动的 内容。 三、从计算机角度看,一个对象应该包含两个要素,一是数 据,二是需要进行的操作。即,对象是一个包含数据以及与这些 数据有关的操作的集合。 四、传统的面向过程的程序设计围绕功能进行,用一个函数 实现一个功能。 五、面向对象程序设计面对的是一个个的对象。 六、面向对象程序设计方法的一个重要的特点就是“封装性” 把数据和操作代码封装在一起。 第三章 C++面向对象基础
3.2 类和对象 一、对象:每一个实体都是对象。 二、类:用来定义对象的一种抽象数据类型,它是产生对象的 模板。它的性质和其他数据类型相同。 三、类的声明: 1、声明一个结构体类型: struct student { int num; char name[20]; char sex; }; struct student stu1,stu2;
2、声明一个类 class stud //以class开头 { int num; char name[20]; char sex; // 以上3行是数据成员 void display() { cout<<“num:”<<num<<endl; cout<<“name:”<<name<<endl; cout<<“sex:”<<sex<<endl; } // 以上是操作代码 }; stud stud1,stud2; //定义了两个类的对象 四、类的成员包括两大类:一类是“私有的”(private); 一类是“公有的”(public)
将上面类的声明改为: class stud { private: //声明以下部分为私有的 int num; char name[20]; char sex; public: //声明以下部分为公有的 void display() { cout<<“num:”<<num<<endl; cout<<“name:”<<name<<endl; cout<<“sex:”<<sex<<endl; } }; stud stud1,stud2; //定义了两个类的对象
五、几个名词: 1、方法:对数据的操作。 2、消息:一个命令,由程序语句来实现。外界通过法送“消息” 来激活有关的方法。 如:stud1.display(); 六、类声明的一般形式: class 类名 { private: 私有的数据和成员函数; public: 公有的数据和成员函数; };
3.3 构造函数和析构函数 一、构造函数 1、构造函数的含义:在建立一个对象时,常常需要作某些初始化 工作,C++提供了一种特殊的成员函数---构造函数来实现。 (1)该函数不需用户发送“消息”来激活它,而是在建立对 象时自动执行,而且只能执行一次。 (2)构造函数由用户定义,必须与类名同名。 (3)构造函数一般声明为public,无返回值,也不需加void 类型声明。
例1、创建一个对象,输出学生的学号、姓名、性别例1、创建一个对象,输出学生的学号、姓名、性别 #include <string.h> #include <iostream.h> void main() { class stud { private: int num; char name[20]; char sex; public: stud() { num=1010; strcpy(name,”wangw”); sex=‘F’; }
void display() { cout<<“num:”<<num<<endl; cout<<“name:”<<name<<endl; cout<<“sex:”<<sex<<endl; } }; stud stud1; stud1.display(); } 说明:(1)程序包括三部分:声明一个类;定义一个对象;向对 象发出消息,执行对象中的成员函数display。 (2)在定义stud1对象时自动执行了构造函数stud()。 (3)输出信息: num:1010 name:wangw sex:F cout<<stud1.name;
2、带参数的构造函数 如:stud(int n,char nam[],char s) { num=n; strcpy(name,nam); sex=s; } 实参在建立对象时给出: 如: stud stud1(1010,”wang_w”,”f”), stud2(1012,”fen”,’m’);
3、构造函数的重载 如:stud(int n,char nam[],char s) { num=n; strcpy(name,nam); sex=s; } stud() { num=1020; strcpy(name,”lili”); sex=‘f’; } 建立对象时允许有实参和无实参: 如: stud stud1,stud2(1012,”fen”,’m’);
4、构造函数可以不定义,编译系统自动生成一个构造函数,该函4、构造函数可以不定义,编译系统自动生成一个构造函数,该函 数没有参数,也不进行任何操作。 二、析构函数 1、析构函数的说明: (1)、析构函数与构造函数相反,当对象脱离作用域时,系统自 动执行析构函数。 (2)、析构函数与类名相同,只是在函数名前面加上一个波浪 符~,如 ~stud(),以区别于构造函数。 (3)、它不带任何参数,也没有返回值。 (4)、析构函数不能重载。 (5)、如果用户没有编写析构函数,编译系统会自动生成一个 缺省的析构函数,它也不进行任何操作。
例2、包含构造函数和析构函数的C++程序。 #include <string.h> #include <iostream.h> class stud { private: int num; char name[20]; char sex; public: stud(int n,char nam[],char s) { num=n; strcpy(name,nam); sex=s; } ~stud() {}
void display() { cout<<“num:”<<num<<endl; cout<<“name:”<<name<<endl; cout<<“sex:”<<sex<<endl; } }; void main() { stud stud1(1010,”Wubin”,’m’); stud1.display(); }
三、成员函数的声明与定义分离 在类中只进行成员函数的声明,在类的外面定义成员函数。 例3、在类的外面定义成员函数。 #include <string.h> #include <iostream.h> class stud { private: int num; char name[20]; char sex; public: stud(int n,char nam[],char s); ~stud() ; void display(); };
stud::stud(int n,char nam[],char s) { num = n; strcpy(name,nam); sex =s; } stud::~stud() {} void stud::display() { cout<<“num:”<<num<<endl; cout<<“name:”<<name<<endl; cout<<“sex:”<<sex<<endl; } void main() { stud stud1(1010,”Wubin”,’m’); stud1.display(); }
说明: 1、在类声明的外部定义的函数,必须指定类名,形式为: 函数类型 类名::函数名(形参表列) 不要写成: void display() //未指定类名 stud::void display() //函数类型位置不对 2、stud::display()是一个整体。 3、可以将在类外部定义的函数声明为“内置函数”。 如:inline void stud::display()
3.3 继承与派生 一、继承与派生的概念 1、面向对象技术强调软件的可重用性,在C++中通过“继承” 机制实现可重用性。 2、继承就是在已存在的类的基础上建立一个新的类。已存在的 类称为“基类”或“父类”,新建立的类称为“派生类”或“子 类”。 3、派生类继承了基类的所有数据成员和成员函数,并增加了新的 成员。
如:声明学生基本数据的类stud class stud { private: int num; char name[20]; char sex; public: void display() { cout<<"num:"<<num<<endl; cout<<"name:"<<name<<endl; cout<<"sex:"<<sex<<endl; } };
学校某部门除了需要学生基本数据外,还需要年龄信息,定义类学校某部门除了需要学生基本数据外,还需要年龄信息,定义类 stud_1 class stud_1 { private: int num; char name[20]; char sex; //前3行原来已有 int age; public: void display() { cout<<"num:"<<num<<endl; cout<<"name:"<<name<<endl; cout<<"sex:"<<sex<<endl; //前3行原来已有 cout<<“age:”<<age<<endl; } };
二、建立派生类的方法 1、例4:通过继承来建立派生类 在基类stud的基础上,声明一个派生类student: class student:public stud { private: int age; public: void display_1() { cout<<“age:”<<age<<endl;} };
说明: (1)class后的student为新建的类名; (2)冒号后面的stud表示已存在的基类; (3)在stud之前有一关键字 public,用来表示基类stud中的 成员在student中的使用权限。 2、定义派生类的一般形式为: class 派生类名:[引用权限]基类名 { 派生类新增加的数据成员; 派生类新增加的成员函数; };
三、公用派生类 1、在声明一个派生类时将基类的引用权限指定为public的,该类 称为基类的公用派生类。 基类 私有成员 公用成员 公用派生类 不可访问的成员 公用成员 公用派生类的继承关系
如:class stud // 声明基类 { private: //基类的私有成员 int num; char name[20]; char sex; public: //基类的公用成员 void display() { cout<<"num:"<<num<<endl; cout<<"name:"<<name<<endl; cout<<"sex:"<<sex<<endl; } };
class student:public stud //声明一个公用派生类 { private: int age; public: void display_1() { cout<<“age:”<<age<<endl; //引用派生类的私有成员 cout<<“num:”<<num<<endl; //错误,引用基类的私有成员 cout<<“name:”<<name<<endl;//错误,引用基类的私有成员 } };
可以通过引用基类的公用成员函数来引用基类的私有数据成员可以通过引用基类的公用成员函数来引用基类的私有数据成员 class student:public stud //声明一个公用派生类 { private: int age; public: void display_1() { display(); //引用基类的公用成员函数 cout<<“age:”<<age<<endl; //引用派生类的私有成员 } };
使用派生类定义对象: main() { student a; //定义了一个student类的对象 a.display_1(); //输出a对象的4的数据 } 主函数中如果出现如下语句: a.display(); //正确。继承公用成员函数。 a.age = 10; //错误。外界不能引用派生类的私有成员 a.num = 1010; //错误。外界不能引用基类的私有成员
四、私有派生类 1、在声明一个派生类时将基类的引用权限指定为 private的,该类 称为基类的私有派生类。 基类 私有成员 公用成员 私有派生类 不可访问的成员 私有成员 私有派生类的继承关系
class student:private stud //声明一个私有派生类 { private: int age; public: void display_1() { display(); //基类的公用成员函数变成派生类的私有函数 cout<<“age:”<<age<<endl; //引用派生类的私有成员 } };
使用派生类定义对象: main() { student a; //定义了一个student类的对象 a.display_1(); //输出a对象的4的数据 } 主函数中如果出现如下语句: a.display(); //错误。基类的公用成员函数变成派生类 // 的私有函数,外界不能引用。 a.age = 10; //错误。外界不能引用派生类的私有成员 a.num = 1010; //错误。外界不能引用基类的私有成员 因此: (1)不能通过私有派生类的对象引用从基类继承过来的任何成员 (2)派生类的成员函数中不能访问基类的私有成员,但可以访问 基类的公用成员。
五、保护成员 1、由protected声明的成员称为保护成员。保护成员不能被外界 引用,但可以被派生类的成员函数引用。 基类 私有成员 公用成员 保护成员 公用派生类 不可访问的成员 公用成员 保护成员 私有派生类 不可访问的成员 私有成员 私有成员 派生类的继承关系
如:class stud // 声明基类 { protected: //基类的保护成员 int num; char name[20]; char sex; public: //基类的公用成员 void display() { cout<<"num:"<<num<<endl; cout<<"name:"<<name<<endl; cout<<"sex:"<<sex<<endl; } };
class student:public stud // 声明公用派生类 { private: int age; public: void display_1() { cout<<“age:”<<age<<endl; //引用派生类私有成员 cout<<“num:”<<num<<endl; //引用基类的保护成员 cout<<"name:"<<name<<endl; } }; void main() { student a; a.display_1(); //合法。 a.num = 1030; // 错误:外界不能访问保护成员 }
六、派生类的构造函数 1、创建派生类的对象时,系统只执行派生类的构造函数,而不会 自动执行基类的构造函数,即,基类的构造函数时不能被继承的。 2、考虑基类的变量初始化,在执行派生类的构造函数时,应当调 用基类构造函数。 例5:派生类的构造函数 #include <string.h> #include <iostream.h> class stud {protected: int num; char name[20]; char sex;
public: stud(int n,char nam[],char s) { num=n;strcpy(name,nam);sex=s; } ~stud() ; }; class student:public stud // 声明公用派生类 { private: int age; public: student(int n,char nam[],char s,int a):stud(n,nam,s) { age=a; //只对派生类新增的变量初始化 } void display_1() { cout<<“age:”<<age<<endl; //引用派生类私有成员 cout<<“num:”<<num<<endl; //引用基类的保护成员 cout<<"name:"<<name<<endl; }
~student(); //派生类的析构函数 } void main() { student a(1020,”liyang”,’f’,19); a.display_1(); //输出学生的数据 } 派生类构造函数首部的写法: 派生类构造函数名(参数表列):基类构造函数名(参数表列) student a(1020, ”liyang” ,’f’, 19); student (int n,char nam[],char s,int a):stud(n,nam,s)
3、在派生类声明中只声明构造函数: student(int n,char nam[],char s,int a): 在类的外面定义派上类构造函数: student::student(int n,char nam[],char s,int a):stud(n,nam,s) { age=a; //只对派生类新增的变量初始化 }