(C++程序设计课件)第四章 面向对象的程序设计

上传人:xins****2008 文档编号:168825868 上传时间:2022-11-12 格式:PPT 页数:48 大小:780.50KB
收藏 版权申诉 举报 下载
(C++程序设计课件)第四章 面向对象的程序设计_第1页
第1页 / 共48页
(C++程序设计课件)第四章 面向对象的程序设计_第2页
第2页 / 共48页
(C++程序设计课件)第四章 面向对象的程序设计_第3页
第3页 / 共48页
资源描述:

《(C++程序设计课件)第四章 面向对象的程序设计》由会员分享,可在线阅读,更多相关《(C++程序设计课件)第四章 面向对象的程序设计(48页珍藏版)》请在装配图网上搜索。

1、1 1C+C+与与C C2 第四章第四章 面向对象的程序设计面向对象的程序设计3class Point public:Point(int a=0,int b=0);void setPoint(int a,int b);int getX()const return x;int getY()const return y;private:int x,y;4class QuadRangle public:QuadRangle(Point p1,Point p2,Point p3,Point p4);QuadRangle();Point getPoint(int index)const;void set

2、Point(const Point&p,int index);void move(int x,int y);void zoom(double x);private:Point v1,v2,v3,v4;新增矩形类新增矩形类rectangle:具有四个顶点;具有四个顶点;能够整体移动、放大缩小;能够整体移动、放大缩小;设置、取得左上、右下顶点;设置、取得左上、右下顶点;计算矩形面积计算矩形面积如何重用四边形类如何重用四边形类?4.1 4.1 继承继承5继承性继承性是面向对象的另一大特点:基于现有的类建立是面向对象的另一大特点:基于现有的类建立新类,新类新类,新类继承继承了现有类的属性(成员变量)和

3、行为了现有类的属性(成员变量)和行为(成员函数),并且(成员函数),并且添加添加自己新的属性和行为。自己新的属性和行为。现有类现有类 基类(父类)基类(父类)新类新类派生类派生类 (子类)(子类)4.1 4.1 继承继承6继承是类之间定义的一种重要关系继承是类之间定义的一种重要关系,定义类定义类B时,时,自动得到类自动得到类A的操作和数据属性,使得程序员只需定的操作和数据属性,使得程序员只需定义类义类A中所没有的新成分就可完成在类中所没有的新成分就可完成在类B的定义,这样的定义,这样称类称类B继承了类继承了类A,类,类A派生了类派生了类B,A是基类(父类),是基类(父类),B是派生类(子类)。

4、这种机制称为继承。是派生类(子类)。这种机制称为继承。称已存在的用来派生新类的类为基类,又称父类。称已存在的用来派生新类的类为基类,又称父类。由已存在的类派生的新类称为派生类,又称为子类。由已存在的类派生的新类称为派生类,又称为子类。自己的数据成员和成员函数。自己的数据成员和成员函数。在在C+语言中,一个派生类可以从一个基类派生,语言中,一个派生类可以从一个基类派生,也可以从多个基类派生。从一个基类派生的继承称为也可以从多个基类派生。从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。单继承;从多个基类派生的继承称为多继承。7class Rectangle:public QuadR

5、angle public:Rectangle(Point leftUp,Point rightDown);Rectangle();int area()const;void setLU(Point leftUp);void setRD(Point rightDown);Point getLU()const;Point getRD()const;private:int area;#include“QuadRangle.h”注意:定义派生类时必须看到基类的定义注意:定义派生类时必须看到基类的定义v1v2v3v4area注意:派生类不能访问基类的注意:派生类不能访问基类的私有成员函数私有成员函数和和私

6、有成员变量私有成员变量,可以访问可以访问公有公有成员成员8Rectangle:Rectangle(Point leftUp,Point rigntDown)Point p1(rightDown.getX(),leftUp.getY();Point p2(leftUp.getX(),rightDown.getY();setPoint(leftUp,1);setPoint(p1,2);setPoint(righDown,3);setPoint(p2,4);/计算面积并保存到计算面积并保存到areaPoint p1(0,5),p2(10,0);Rectangle rt(p1,p2);int area

7、=rt.area();rt.zoom(10);rt.move(0,10);调用基类的调用基类的公有成员公有成员9class QuadRangle public:protected:Point v1,v2,v3,v4;protected:派派生类可以直接生类可以直接访问访问Rectangle:Rectangle(Point leftUp,Point rigntDown)v1=leftUp;v2.setPoint(rightDown.getX(),leftUp.getY();v3=righDown;v4.setPoint(leftUp.getX(),rightDown.getY();/计算面积并保

8、存到计算面积并保存到area104.2 4.2 继承方式继承方式基类成员基类成员访问符访问符继承方式继承方式public继承继承protected继承继承private继承继承public在派生类中为在派生类中为public对外可见对外可见在派生类中为在派生类中为protected允许允许成员函数、友元、新成员函数、友元、新的派生类访问的派生类访问在派生类中为在派生类中为private允许允许成员函数、友元访成员函数、友元访问问protected在派生类中为在派生类中为proteced允许成员函数、友元、允许成员函数、友元、新的派生类访问新的派生类访问在派生类中为在派生类中为protected

9、允许允许成员函数、友元、新成员函数、友元、新的派生类访问的派生类访问在派生类中在派生类中private允许允许成员函数、友元访成员函数、友元访问问private在派生类中隐藏在派生类中隐藏在派生类中隐藏在派生类中隐藏在派生类中隐藏在派生类中隐藏11#include“QuadRangle.h”class Rectangle:private QuadRangle public:int area()const;private:int area;Point p1(0,5),p2(10,0);Rectangle rt(p1,p2);int area=rt.area();rt.zoom(10);rt.mo

10、ve(0,10);12class Rectangle:public QuadRangle public:Rectangle(Point leftUp,Point rightDown);Rectangle();class QuadRangle public:QuadRangle(Point p1,Point p2,Point p3,Point p4);QuadRangle();private:Point v1,v2,v3,v4;Point p1(0,5),p2(10,0);Rectangle rt(p1,p2);?如何构造派生类?如何构造派生类134.3 4.3 派生类的构造与析构派生类的构造与

11、析构新建一个类新建一个类A A的对象时,构造函数的调用顺序总是如下:的对象时,构造函数的调用顺序总是如下:先看类先看类A A否有基类,若有则调用基类构造函数否有基类,若有则调用基类构造函数看类看类A A是否有成员类对象,若有则调用成员类对象构造函是否有成员类对象,若有则调用成员类对象构造函数数,如果有多个成员类对象,则构造函数的调用顺序是对,如果有多个成员类对象,则构造函数的调用顺序是对象在类中被声明的顺序。象在类中被声明的顺序。类类A A构造函数构造函数14Point p1(0,5),p2(10,0);Rectangle rt(p1,p2);class Rectangle:public Qu

12、adRangle public:Rectangle(Point leftUp,Point rightDown);Rectangle();class QuadRangle public:QuadRangle(Point p1,Point p2,Point p3,Point p4);QuadRangle();private:Point v1,v2,v3,v4;class Point public:Point(int a=0,int b=0);1(调用四次)(调用四次)1115注意:作为一般规则,注意:作为一般规则,派生类构造函数不应该派生类构造函数不应该直接向一个直接向一个基基类数据成员赋值类数据

13、成员赋值,而是把值传递给适当的基类构造函数,否,而是把值传递给适当的基类构造函数,否则两个类的实现变成则两个类的实现变成紧耦合紧耦合的。的。Rectangle:Rectangle(Point leftUp,Point rigntDown)v1=leftUp;v2.setPoint(rightDown.getX(),leftUp.getY();v3=righDown;v4.setPoint(leftUp.getX(),rightDown.getY();16class Person public:Person(const char*str=NULL,int a=0);protected:char*

14、name;int age;classStudent:public Person public:Student(const char*str=NULL,int a=0,int i=0);private:intid;Student:Student(const char*str,int a,int i):Person(str,a),id(i)17析构函数调用顺序与它的构造函数调用顺序相反,析构函数调用顺序与它的构造函数调用顺序相反,类类A A的对象生命期结束时,析构函数调用顺序为:的对象生命期结束时,析构函数调用顺序为:类类A A析构函数析构函数;看类看类A A是否有成员类对象是否有成员类对象,若有

15、则调用成员类对象,若有则调用成员类对象析构函数;析构函数;看类看类A A否有基类否有基类,若有则调用基类析构函数。,若有则调用基类析构函数。18class Person public:Person ;Person:Person()delete name;classStudent:public Person public:Student();Student:Student()delete name;Student*ptr=new Student(“liping”,18,2);delete ptr;12删除两次删除两次namename!基类构造函数分配的存储空间,一般由基类的析基类构造函数分配的存

16、储空间,一般由基类的析构函数释放构函数释放19person.hclassPerson;student.h#include“person.h”classStudent:public Person;#include“student.h”#include“person.h”void main()Person zhangSan(“ZhangSan”,45);Student zhangSi(“ZhangSi”,18,10);类类Person的重复定义的重复定义person.h#ifndefPERSON#definePERSONclassPerson;#endif20class Person public

17、:/改变年龄改变年龄void changeInfo(int a);class Student:public Person public:/改变学号改变学号void changeInfo(int i);/改变年龄、学号改变年龄、学号void changeInfo(int a,int i);Student lisi(“lisi”,18,10);lisi.changeInfo(20);4.4 4.4 重定义重定义21重定义:重定义:派生类中的成员与基类中的成员派生类中的成员与基类中的成员同名同名时(不时(不会产生重复定义错误),派生类中的成员定义将会产生重复定义错误),派生类中的成员定义将覆覆盖盖基

18、类中的成员定义(基类中的成员定义(重定义重定义)。对于成员函数,)。对于成员函数,若函数名相同,参数不同,若函数名相同,参数不同,不会形成函数重载不会形成函数重载。class Person public:/改变年龄改变年龄void changeInfo(int a);protected:int id;/身份证号身份证号;class Student:public Person public:/改变年龄、学号改变年龄、学号void changeInfo(int a,int i);private:int id;/学号学号;Student lisi(“lisi”,18,10);lisi.changeI

19、nfo(20,1);lisi.changeInfo(1101850101);22void Student:changeInfo(int a,int i)age=a;id=i;Student:id在在Student的成的成员函数中直接访员函数中直接访问问Person中的中的id:Person:id234.5 4.5 类型兼容规则类型兼容规则class Parent;class Son:public Parent;Son xiaoLi;Parent laoLi=xiaoLi;Parent *ptr=&xiaoLi;Parent laoWang;Son xiaoWang=laoWang;?24类型兼

20、容规则是指在需要类型兼容规则是指在需要基类对象基类对象的任何地方,都的任何地方,都可以使用公有可以使用公有派生类的对象来替代派生类的对象来替代。包括以下情况:。包括以下情况:派生类的对象可以赋值给基类对象;派生类的对象可以赋值给基类对象;派生类的对象可以初始化基类的应用;派生类的对象可以初始化基类的应用;派生类对象的地址可以赋给指向基类的指针。派生类对象的地址可以赋给指向基类的指针。在替代之后,派生类对象就可以在替代之后,派生类对象就可以作为基类的对象作为基类的对象使使用,但用,但只能使用从基类继承的成员只能使用从基类继承的成员。25class Parent;class Son:public

21、Parent;Son xiaoLi;Parent laoLi,*ptr;laoLi=xiaoLi;Parent&ref=xiaoLi;ptr=&xiaoLi;Parent laoWang;Son xiaoWang=laoWang;26#include using namespace std;class B0 public:void display()cout“B0:display”endl;class B1:public B0 public:void display()cout“B1:display”endl;class D1:public B1 public:void display()co

22、ut“D1:display”display();int main()B0 b0;B1 b1;D1 d1;fun(&b0);fun(&b1);fun(&d1)输出?输出?B0:displayB0:displayB0:display27class Person public:/打印姓名、年龄打印姓名、年龄void print();protected:char*name;int age;class Student:public Person public:/打印姓名、年龄、学号打印姓名、年龄、学号void print();private:int id;class Employee:public Pe

23、rson public:/打印姓名、年龄、职务、薪水打印姓名、年龄、职务、薪水void print();private:char*title;double salary;/打印个人信息的全局函数打印个人信息的全局函数void print(*one)one-print();?4.6 4.6 多态多态28用基类的指针或引用操纵多个派生类的能力被称用基类的指针或引用操纵多个派生类的能力被称为为多态多态/打印个人信息打印个人信息void print(Person*one)one-print();Student lisi(“lisi”,18,1);Employee lisan(“lisan”,30,“M

24、anager”,2000);print(&lisi);print(&lisan);自动被转换成自动被转换成Person*29在运行时刻需要解析出被调用的函数,这个解析过程被称为在运行时刻需要解析出被调用的函数,这个解析过程被称为动态绑定动态绑定(dynamic bindng)。缺省情况下,函数是在编)。缺省情况下,函数是在编译时刻被译时刻被静态解析静态解析的。的。在在C+中通过一种被称为中通过一种被称为虚函数虚函数的机制来支持动态绑定。的机制来支持动态绑定。通过继承和动态绑定,使类的多态性得到体现通过继承和动态绑定,使类的多态性得到体现30class Person public:/打印姓名、年

25、龄打印姓名、年龄virtual void print();class Student:public Person public:/打印姓名、年龄、学号打印姓名、年龄、学号virtual void print();class Employee:public Person public:/打印姓名、年龄、职务、薪水打印姓名、年龄、职务、薪水 virtual void print();必须在类声明中指定必须在类声明中指定virtual 关键字,关键字,在类外定义函数时不能再次指定在类外定义函数时不能再次指定关键字关键字virtual void Student:print()31/打印个人信息打印个人

26、信息void print(Person*one)one-print();Student lisi(“lisi”,18,1);Employee lisan(“lisan”,30,“Manager”,2000);print(&lisi);print(&lisan);动态绑定到动态绑定到Student:print()动态绑定到动态绑定到Employee:print()注意:必须是注意:必须是指向基类的指针或指向基类的指针或引用引用才能实现动态绑定才能实现动态绑定32使用虚函数时应注意:使用虚函数时应注意:(1)在类体系中访问一个虚函数时,应使用指向基类)在类体系中访问一个虚函数时,应使用指向基类类型

27、的指针或对基类类型的引用,以满足运行时多态类型的指针或对基类类型的引用,以满足运行时多态性的要求。当然也可以像调用普通成员函数那样利用性的要求。当然也可以像调用普通成员函数那样利用对象名来调用一个函数。对象名来调用一个函数。(2)在派生类中重新定义虚函数时,必须保证该函数)在派生类中重新定义虚函数时,必须保证该函数的值和参数与基类中的说明完全一致,否则就属于重的值和参数与基类中的说明完全一致,否则就属于重载(参数不同)或是一个错误(返回值不同)。载(参数不同)或是一个错误(返回值不同)。(3)若在派生类中没有重新定义虚函数,则该类的对)若在派生类中没有重新定义虚函数,则该类的对象将使用其基类中

28、的虚函数代码。象将使用其基类中的虚函数代码。(4)虚函数必须是类的一个成员函数,不能是友元,)虚函数必须是类的一个成员函数,不能是友元,但它可以是另一个类的友元。另外,虚函数不得是一但它可以是另一个类的友元。另外,虚函数不得是一个静态成员。个静态成员。33假如要设计一个绘图系统,要求每类假如要设计一个绘图系统,要求每类图形可以:图形可以:绘图(显示)绘图(显示)移动移动放大、缩小放大、缩小如何控制每类图形如何控制每类图形都必须提供上述接口呢?都必须提供上述接口呢?4.6 4.6 抽象类抽象类class Shape public:void draw();voidmove(int x,int y)

29、;voidzoom(double x);34纯虚函数纯虚函数:赋值为:赋值为0的虚函数。的虚函数。抽象类抽象类:含有一个或多个纯虚函数的类。:含有一个或多个纯虚函数的类。不能不能用来定义对象,只能作为基类用来定义对象,只能作为基类。class Shape public:virtual void draw()=0;virtual voidmove(int x,int y)=0;virtual voidzoom(double x)=0;用来定义用来定义公共接口公共接口35class Circle:public Shape public:virtual void draw();virtual voi

30、dmove(int x,int y);virtual voidzoom(double x);注意:如果派生类没有实现所有基类的纯虚函数,则注意:如果派生类没有实现所有基类的纯虚函数,则该派生该派生类也是一抽象类类也是一抽象类,即不能用来定义对象。,即不能用来定义对象。3636class Person public:protected:char*name;int age;classStudent:public Person public:private:char*school;char*class;intid;class Employee:public Person public:private

31、:char*company;char*job;double salary;如何定义代培生?如何定义代培生?是一名职员是一名职员是一名学生是一名学生4.7 4.7 多继承多继承3737多继承:一个派生类有多继承:一个派生类有两个或者两个以上两个或者两个以上的的直接直接基类基类class EmployStud:public Student,public Employee public:private:bool way;逗号逗号,隔开隔开的多个基类的多个基类3838EmployStudliming;wayschoolnamecompanyname多个基类对象,多个基类对象,二义性:二义性:有两个有两

32、个name/agePersonnameageEmployeecompanyjobsalaryStudentschoolclassidEmployStudway存储空间浪费存储空间浪费不便于维护不便于维护3939虚拟继承:无论基类在派生层次中出现多少次,虚拟继承:无论基类在派生层次中出现多少次,只有一个只有一个共共享的基类子对象被继承。享的基类子对象被继承。class Student:virtual public Person;class Employee:public virtual Person;class EmployStud:public Student,public Employee;

33、EmployStudliming;wayschoolcompanynamevirtual可在可在继承关键字继承关键字之前或之后之前或之后4040IBMIBM库的头文件:库的头文件:stringstringlistliststackstackMicrosoftMicrosoft库的头文件:库的头文件:vectorvectorqueuequeuestackstackvoid main()void main()/使用数据类型使用数据类型listlist和和queuequeue/包含包含IBMIBM库的头文件库的头文件/包含包含MicrosoftMicrosoft库的头文件库的头文件造成造成stack

34、stack定义冲定义冲突突4.8 4.8 名字空间名字空间4141名字空间定义格式:名字空间定义格式:namespace namespace 空间名空间名 /成员定义成员定义所有可以出现在全局域中的所有可以出现在全局域中的声明都可以放在用户声明的声明都可以放在用户声明的名字空间中:类定义、变量名字空间中:类定义、变量声明或定义、函数声明或定声明或定义、函数声明或定义。义。名字空间括起来的区域称为名字名字空间括起来的区域称为名字空间域,出现在名字空间域中的空间域,出现在名字空间域中的各种声明或定义只能在该域中直各种声明或定义只能在该域中直接使用接使用4242cstring.hnamespaceM

35、yString class CString;CString&operator+(const char*,CString&);cstring.cppnamespaceMyString CString:CString()CString&operator+(const char*str1,CString&str2)注意:名字空间的定义不一定是连续的,可以放在不同文件中。注意:名字空间的定义不一定是连续的,可以放在不同文件中。对外接口对外接口实现实现4343注意:名字空间可以嵌套定义注意:名字空间可以嵌套定义mylib.hnamespaceMyLib class CString;namespaceMa

36、thLib class Complex;namespaceGraphicLib classCircle;4444名字空间的使用(名字空间的使用(1 1):):空间名空间名:成员名成员名域操作符域操作符#include“mylib.h”void main()CString str(“hello”);MyLib:CString str(“hello”);MyLib:GraphicLib:Circle cir;4545名字空间的使用(名字空间的使用(2 2):):定义名字空间定义名字空间别名别名#include“mylib.h”namespacegraph=MyLib:GraphicLib;void

37、 main()graph:Circle cir;4646名字空间的使用(名字空间的使用(3 3):):usingusing 空间名空间名:成员名;成员名;#include“mylib.h”using MyLib:GraphicLib:Circle;using MyLib:CString;void main()CString str;Circle cir;4747名字空间的使用(名字空间的使用(4 4):):usingusing 空间名;空间名;#include“mylib.h”using MyLib;void main()CString str;Circle cir;Complex cp;48

38、48作业作业4 4:定义一个类定义一个类UpperCaseUpperCase,要求:,要求:n 该类继承自该类继承自MyStringMyString类类(第三次作业定义的,可作修改)第三次作业定义的,可作修改)n 该类实例表示的字符串中不包含小写字符,遇到小写字符时,将自动该类实例表示的字符串中不包含小写字符,遇到小写字符时,将自动转变为大写字符,其它字符不变。例如:转变为大写字符,其它字符不变。例如:UpperCase str(“Hello worldUpperCase str(“Hello world!”););/HELLO WORLD/HELLO WORLD!str+=“No 25”;str+=“No 25”;/HELLO WORLD!NO 25/HELLO WORLD!NO 25n 能够实现父类的所有行为(考虑哪些可以继承,哪些需要重定义);能够实现父类的所有行为(考虑哪些可以继承,哪些需要重定义);n 能够以下述形式输入、输出字符串:能够以下述形式输入、输出字符串:UpperCaseUpperCasestr,str1,str2;str,str1,str2;cinstr1;cinstr1;coutstr1str2;coutstr1str2;

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!