版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、面向对象程序设计基础课件面向对象程序设计基础课件6.1 面向对象程序设计(OOP)概述基本概念 Object Oriented Programming 对象:现实世界的实体,每个对象都有所属的类 类: 对一组对象共同具有的属性和行为的抽象, 具有封装和隐藏性、还具有继承性。 消息:向某对象请求服务的一种表达方式,是对 象与外界、对象与其它对象之间联系的工具 方法:对某对象接受消息后所采取的操作的描述。6.1 面向对象程序设计(OOP)概述基本概念 Object特点封装性继承性多态性C+中,通过类和对象实现对数据的封装,使得程序的修改维护更方便。是OOP的基础。连接类与类的层次模型,利用现有类派
2、生出新类的过程称为类继承,支持代码重用、提供了无限重复利用程序资源的途径、节省程序开发的时间和资源,是OOP的关键。发出同样的消息被不同类型的对象接收时导致完全不同的行为,是OOP的重要补充特点C+中,通过类和对象实现对数据的封装,使得程序的修改说明结构类型的关键字 6.2 结构C+中的类从C语言中的结构概念演变而来 结构类型说明形式struct 结构类型标识符结构成员1; 结构成员2;结构成员n;类型可任意(不能为该结构自身)说明结6.2 结构C+中的类从C语言中的结构概念演变而来 struct date int month; int day; int year; struct man ch
3、ar name15; char sex; int age; date birthday;如,说明一个结构类型date,含三个整型数据成员在此基础上,又可说明另一个结构类型manbirthdayNamesexagemonthdayyear struct man结构类型struct date struct man如,说明一个结构变量定义先说明结构类型再定义结构变量在说明结构数据类型的同时定义结构变量省略结构标识符直接定义结构类型变量struct man man1, man2;struct man char name15;char sex;int age; struct date birthday;
4、 man1, man2;struct char name15;char sex;int age; struct date birthday; man1, man2;无类型名变量结构变量定义先说明结构类型再定义结构变量struct man结构变量的引用形式: 结构变量名.成员名(*指向结构的指针).成员名 指向结构的指针-成员名或或通过指向结构的指针引用结构变量成员成员访问运算符优先级最高的四个运算符之一 括号不能少如,假设有定义man m,*p=&m; strcpy (, Fang Min);p-birthday.month = 8; 则可如下引用结构成员结构变量的引用形式: 结构
5、变量名.成员名或或通过指6.3 类和对象引例定义一有关职工工资信息的结构类型,对某职工的该类信息进行处理。职工信息包括姓名、基本工资、岗位工资和职务工资;对该类信息的处理包括输入、输出和求总收入情况。 #include iostream.hstruct stuffchar name10; double jw,gw,zw;s ; void print( ):s.jws.gws.zw;double salary( )double sum=0; sum=sum+s.jw+s.gw+s.zw; return sum;void main()in
6、put( ); print( ); coutsalary( );结构化的方法6.3 类和对象引例定义一有关职工工资信息的结构类型,对结构化程序的框架结构化程序结构化程序的框架结构化程序#include iostream.hclass stuffprivate: char name10; double jw,gw,zw;public:void print( )coutname:jwtgwtzwnamejwgwzw; double salary( )double sum=0; sum=sum+jw+gw+zw; return sum;void main()stuff s; s.input( );
7、s.print( ); couts.salary( );以面向对象的方式实现#include iostream.hdouble sa面向对象程序设计基础课件6.3.1 类的定义类是一种复杂的数据类型,它是将不同类型的数据和与这些数据相关的运算封装在一起的集合体,定义格式:class 类名public: ; private: ; protected: ;; 6.3.1 类的定义类是一种复杂的数据类型,它是将不同类型说明:定义包括说明部分和实现部分。若成员函数在说明部分已定义,则实现部分可省略;若成员函数在类体外实现,需用类名和作用域运算符(:)标识所属类。访问权限修饰符:public(公有)、p
8、rivate(私有 )和 protected(保护) 缺省时为private。公有成员通常为成员函数,可在程序中引用,私有成员通常是数据成员,只有成员函数或友元函数才可引用。类体中不允许对数据成员初始化。class Bprivate: int year=2002, month=10, day=12;错说明:class B错 例6-1:定义一个Circle类(圆类),包括如下的一些数据成员 和成员函数.数据成员成员函数名称含义名称功能x圆心坐标x值set设置数据成员值y圆心坐标y值print输出数据成员值r圆半径area求圆的面积lenth求圆的周长 例6-1:定义一个Circle类(圆类),包
9、括如下的一class Circleprivate: double x,y,r; public: void print( ); void set(double x1,double y1,double r1); double area( ) return (3.14*r*r); double lenth() return(2*3.14*r);void Circle:print()cout圆心:(x,y)endl; cout半径:r成员名类成员的访问方式类内: (成员函数访问数据成员)直接访问类成员类外: (外部程序访问类的成员函数)访问方式同结构成员,具体如下:对象名成员名类成员的访问方式例6-2
10、编制主函数,通过例6-1中定义的Circle类,对圆心在原点,半径为2的圆和圆心在点(1,1)上,半径为4的圆进行测试。 void main()Cirlce p1,*p2; p1.set(0,0,1); p1.print( ); coutp1.areatp1.lenthset(1,1,4); p2-print( ); coutareatlenthendl;例6-2编制主函数,通过例6-1中定义的Circle类,6.3.3 对象的初始化1.构造函数和析构函数例6-3 看例6-2的另一种实现class Circleprivate: double x,y,r; public: void print(
11、 ); Circle(double x1,double y1,double r1); double area( ) return (3.14*r*r); double lenth() return(2*3.14*r);Circle:Circle(double x1,double y1,double r1) x=x1; y=y1; r=r1;/其它函数实现略void main() Circle p (0,0,2); p.print(); 1.定义的同时初始化对象2.省略对赋初值成员函数的额外调用6.3.3 对象的初始化class Circlevoi构造函数特点析构函数特点:若一个对象被定义在函数
12、体内,则当该函数结束时, 该对象的析构函数被自动调用。当一个对象是使用new运算符被动态创建的,在使用delete释放时,析构函数将会被自动调用是成员函数,可写在类体内,亦可写在类体外。函数名同类名,不能指定函数类型,可以带参数。可重载,即可定义多个参数个数不同的函数。在创建对象时由系统自动调用,程序中不能直接调用。是成员函数,可写在类体内,亦可写在类体外。函数名同类名,前面多个字符“” ,不指定类型,无参。不可重载,即一个类只能定义一个析构函数。可被调用,也可由系统调用。系统自动调用情况如下:构造函数特点若一个对象被定义在函数体内,则当该函数结束时, 2.缺省构造函数和缺省析构函数形式:说明
13、:若没有定义任何构造函数,系统会自动生成上述无参的缺省构造函数及析构函数若定义一个静态对象而没有指明初始化时,编译器会按缺省构造函数对对象的所有数据成员都初始化为或空。 :() :( ) 2.缺省构造函数和缺省析构函数:缺省析构函数名例6.3 定义一个Circle1类,具有求一个圆的面积、求两个圆的面积之和,以及输出面积等功能 。#include iostream.hclass Circle1private: double x,y,r,s; public: void print()cout圆心:(x,y)endl; cout半径:rendl; Circle1() Circle1(double
14、x1,double y1,double r1) x=x1; y=y1; r=r1; void addarea(Circle1 p1,Circle1 p2) s=3.14*(p1.r*p1.r)+3.14*(p2.r*p2.r); void disp() cout面积:sendl;void main() Circle1 p1(0,0,2),p2(1,1,4),p3; p1.print(); p2.print(); p3.addarea(p1,p2); p3.disp();可缺省吗?验证一下初始化了吗例6.3 定义一个Circle1类,具有求一个圆的面积#include #include clas
15、s countint num; public: count(); count(); void process(); ; count:count() num=0;count:count() cout字符个数:numendl; void count:process() while(cin.get()!=n) num+; coutendl; void main()count c; cout输入一个句子: ; cess();例6.4 析构函数示例析构函数中输出处理结果(未设专门输出函数)析构函数在程序结束前由系统自动调用#include count:c3.拷贝初始化构造函数 例6.5#inc
16、lude iostream.hclass Circle1private: double x,y,r,s; public: void print() cout圆心:(x,y)endl; cout半径:rendl; Circle1(double x1,double y1,double r1) x=x1; y=y1; r=r1;Circle1( Circle1 &p)x=p.x; y=p.y, r=p.r;void main()Circle1 p1(0,0,2),p2(p1); p1.print(); p2.print();用于用已知对象初始化被创建的同类对象只有一个参数,且是对某个对象的引用常用于
17、做函数的形参及返回值拷贝初始化构造函数(引用做参数)已知对象做初值3.拷贝初始化构造函数#include iostream.6.3.4常对象和常成员 1.常成员函数形式:类型说明符 函数名(参数表) const不修改对象数据成员的成员函数才能声明为const函数构造函数和析构函数不能声明为const只有常成员函数可以操作常对象说明:例6.6常成员函数示例6.3.4常对象和常成员 1.常成员函数类型说明符 函数名#include iostream.hclass Timeprivate: int hour,minute,second; public: Time:Time() Time:Time(i
18、nt h,int m,int s) hour=h; minute=m; second=s; void settime(int h,int m,int s) hour=h; minute=m; second=s; void print()const couthour:minute:secondendl;void main()Time t1; const Time t2(10,23,34);/定义t2为常对象 t1.settime(11,15,20); t1.print(); /t2.settime(4,12,15); t2.print();前面的解释符可去掉吗不修改数据成员,定义为常函数sett
19、ime函数可声明为const吗#include iostream.h前面的解释符可去掉2.常数据成员 对不应该被修改的数据成员声明为const,可使其受到强制保护,初始化方式与一般数据成员不同。class Decrement private: int num; const int dec; /将dec声明为常数据成员 public: Decrement(int n,int d):dec(d) num=n; void fdec() num=num-dec; void print()const coutnum=num,dec=decendl; ;初始化列表的方式初始化2.常数据成员 对不应该被修改
20、的数据成员声明为cons6.3.5静态成员 静态成员的提出是为了解决数据共享的问题,它比全局变量在实现数据共享时更为安全,是实现同类多个对象数据共享的好方法。在类中,分为静态数据成员和静态函数。1。静态数据成员初始化格式:数据类型 类名:静态数据成员=值是类的成员,被所有对象所共享,在内存中只存贮一次定义或说明时前面加关键字static初始化在类外进行,不加static和访问权限修饰符6.3.5静态成员数据类型 类名:静态数据成员=值是类例6.7 静态数据成员示例程序 通过以下程序了解静态数据成员的声明、初始化的位置和限定及具有类对象共享的属性。#include class Tcprivate
21、: int i; static int k; public: Tc( ) i=0; i+; k+; void display() couti,1创建B时k值1-2。1,21,2例6.7 静态数据成员示例程序#include io2.静态成员函数调用形式: 静态成员函数中数据成员的引用也有区别: 例6.8静态成员函数应用程序示例静态成员函数是类的成员函数,而非对象的成员。类名:静态成员函数名(参数表)对静态数据成员,直接引用对非静态数据成员,通过对象引用2.静态成员函数静态成员函数是类的成员函数,而非对象的成员。#include class Tcprivate: int A; static in
22、t B; public: Tc(int a) A=a; B+=a; static void display(Tc C) coutC.AB; ;int Tc:B=2;void main() Tc A(2),B(4); Tc:display(A); Tc:display(B); 静态成员函数的调用非静态数据成员的引用静态数据成员的引用 通过该程序了解程序中静态成员函数的调用方式以及静态成员函数中静态数据成员和非静态数据成员的引用方式#include void main6.3.6 友元函数 例6.9友元函数示例程序#include #include class Cpointprivate: int
23、X,Y; public: Cpoint(int x, int y) X=x; Y=y; void print(); friend double dist(Cpoint &a,Cpoint &b); ;void Cpoint:print() coutXY ;double dist(Cpoint &a,Cpoint &b) int dx=a.X-b.X; int dy=a.Y-b.Y; return sqrt(dx*dx+dy*dy);void main()Cpoint p1(3,4),p2(6,8); p1.print(); p2.print(); double d=dist(p1,p2); /
24、*友元不是成员函数不需对象表示,直接调用*/ coutDistance is dendl; 友元函数说明前不能加 friend为非成员函数可访问类中私有成员说明时前面加关键字friend标识6.3.6 友元函数#include iostream.h计算机系人员学生研究生本科生系主任行政管理人员教务教师教职工6.4 继承和派生基类(父类)派生类(子类)多继承单继承计算机系人员学生研究生本科生系主任行政管理人员教务教师教职工class Cylinder1:public Circleprivate: double h; public: void print() Circle:print(); cou
25、t圆柱高:hendl; void set(double x1,double y1, double r1,double h1) Circle:set(x1,y1,r1); h=h1; ;class Cylinderprivate: double x,y,r,h; public: void print() cout圆心:(x, y)endl; cout半径:r ,圆柱高:hendl; void set(double x1,double y1, double r1,double h1) x=x1; y=y1; r=r1; h=h1;对比如下两个圆柱体类的定义全部数据成员重新定义只定义一个新成员(Ci
26、rcle中没有)通过调用Circle类成员函数输出Circle类成员从Circle类中派生而来class Cylinder1:public Circle6.4.2单继承 1.派生类的定义格式原有类(父类)class 派生类名: 继承方式 基类名 派生类新定义成员;public(公有基类)private(私有基类)protected(保护基类) 若要在派生类Cylinder1中再增加一个成员函数volume,用以求圆柱体的体积,则该成员函数能否如下实现:double Cylinder1:volume()return(3.14*r*r*h);错!r是Circle类的私有成员,不能被派生类访问6.4
27、.2单继承 原有类(父类)class 派生类名: 继承2.继承方式public,private和protected 是三种常用的继承方式,继承方式的不同决定了派生类对基类成员的访问权限不同。基类私有成员(private) 公有成员(public)保护成员(protected)私有派生类(private)不可访问的成员私有成员私有成员公有派生类(public)不可访问的成员公有成员保护成员保护派生类(protected)不可访问的成员保护成员保护成员派生类的继承关系2.继承方式基类私有成员公有成员保护成员私有派生类不可访问的例6.10分析下列程序中的访问权限,并回答所提的问题。#include
28、class Apublic: void f1(); A( ) i1=10;j1=11; protected: int j1; private: int i1; ;class B:public Apublic: void f2( ); B( ) i2=20;j2=21; protected: int j2; private: int i2; ;class C:public Bpublic: void f3(); C( ) i3=30;j3=31; protected: int j3; private: int i3; ;void main()A a; B b; C c; (1) f2()能否访问
29、f1(),i1,j1?能访问f1()、j1,不能访问i1(2) 能否访问f(),i1,j1?能访问f1(),不能访问i1和j1(3) f3()能否访问f2()、i2和j2,以及f1(),j1和i1?f3能访问f2()和j2,以及f1()和j1,但不能访问i1和i2(4)c能否访问f2(),i2和j2?以及f1(),j1和i1?能访问f2()和f1(),其它的都不能访问例6.10分析下列程序中的访问权限,并回答所提的问题。#include iostream.hclass Circleprivate: double x,y,r; public: void print() cout圆心:(x,y);
30、 coutendl半径:rendl; void set(double x1,double y1,double r1) x=x1; y=y1; r=r1; double getr() return r;class Cylinder1:public Circleprivate: double h; public: void print() Circle:print(); cout圆柱高:hendl; void set(double x1,double y1, double r1,double h1) Circle:set(x1,y1,r1); h=h1; double volume() doubl
31、e R=getr(); return(3.14*R*R*h); ;void main()Cylinder1 p; p.set(0,0,2,3); p.print(); coutvolume=p.volume(); 该函数返回值为圆半径,为派生类能使用半径提供一个接口 派生类可访问基类公有成员例6.11派生类示例程序#include iostream.hclass Cyl3.构造函数和析构函数 派生类的构造函数除了对自己的数据成员初始化外,还负责调用基类构造函数使基类的数据成员得以初始化,当对象被删除时,派生类的析构函数被执行,同时基类的析构函数也将被调用。格式:派生类名(派生类构造函数总参数表
32、):基类构造函数(参数表1) ; 基类中有缺省的构造函数或没定义构造函数,则派生类构造函数的定义中可省略对基类构造函数的调用,而隐式调用缺省构造函数。基类构造函数中,只有有参的构造函数,则派生类构造函数中必须 调用基类构造函数,提供将参数传递给基类构造函数的途径派生类构造函数的调用顺序为先基类,后派生类。派生类析构函数的执行顺序为先派生类,后基类。 说明:3.构造函数和析构函数派生类名(派生类构造函数总参数表):基#includeiostream.h#include string.hclass Staffprivate: char name30; char sex; float wage; p
33、ublic:void display()coutname:sex, ageendl; Staff(char *n,char s,float w) strcpy(name,n); sex=s; wage=w; ;class Staff1:public Staffprivate: int wt;public:Staff1(char *n,char s,float w,int t):Staff(n,s,w)wt=t;double addwage()return(wt/10*80);void display() Staff:display(); coutwt, addwage()endl;void m
34、ain()Staff1s(WangQiang,m,1526,21); s.display();例6.12派生类构造函数示例程序派生类构造函数中调用基类构造函数 #includeiostream.hclass Staf6.5多态性 发出同样的消息被不同类型的对象接收时导致完全不同的行为。函数重载(已介绍过)运算符重载基于虚函数的多态性6.5.1 运算符重载 赋予已有的运算符多重含义,通过重新定义运算符使它能够用于特定类的对象以完成特定的功能。 例6.13重载“+”运算 ,用以实现两个字符串的连接 6.5多态性 函数重载(已介绍过)6.5.1 运算符重载 #include iostream.h#i
35、nclude string.h#include stdio.hclass Strprivate: char *s; int len; public: Str() Str(char *s1) len=strlen(s1); s=new charlen; strcpy(s,s1); void print() coutsendl; Str operator+(Str s1) return(strcat(s,s1.s); ;void main() char str1100,str2100; gets(str1); gets(str2); Str s1(str1),s2(str2),s3; s3=s1+
36、s2; s3.print();对加法运算符进行重载 s3=s1.operator+(s2) #include iostream.hvoid main重载形式:重载为类的成员函数:类名 operator 运算符(参数表)程序中表达形式:c1 运算符 c2编译程序解释形式:c1 operator 运算符(c2)重载为类的友元函数:friend类名operator运算符(参数表)程序中表达形式:c1 运算符 c2编译程序解释形式:operator 运算符(c1,c2)将例6.13中的加法运算符重载为友元函数的形式如下:friend Str operator+(Str s1,Str s2)return
37、(strcat(s1.s,s2.s);隐含了指向c1的this指针重载形式:重载为类的成员函数:重载为类的友元函数:将例6.1this 指针 无需定义而隐含于每个类的成员函数中指向正在被某个成员函数操作的对象可以用*this来标识调用该成员函数的对象通常情况下,程序中并不显式地使用this指针 例6.14自增运算符重载(this 指针使用示例)this 指针 例6.14自增运算符重载(this 指针#include iostream.hclass Aprivate: int x; public: A(int x1) x=x1; void print() coutxendl; A operato
38、r+() x+; return(*this); ;void main()A a(5); (+a).print();返回调用成员函数的对象自身 自增重载运算作用于A类对象a等价于如下两条语句:+a;a.print();#include iostream.h返回调用成员函数的6.5.3虚函数虚函数说明方式 虚函数是动态联编的基础,它是一种非static的成员函数实现动态联编的条件virtual 类型说明符 函数名 (参数表)基类中有说明的虚函数调用虚函数操作的只能是对象指针或对象引用,否则仍为静态联编例6.15虚函数示例程序 6.5.3虚函数虚函数说明方式virtual 类型说明符 #includ
39、e iostream.hclass Animalpublic: void character() cout动物特征:不同.n; virtual food() cout动物食物:不同.n;class Giraffe:public Animalpublic: void character() cout长颈鹿特征:长颈.n; virtual food() cout长颈鹿食物:树叶.n;class Elephant:public Animalpublic: void character()cout大象特征:长鼻子.n; virtual food() coutcharacter(); p-food();
40、void main()Giraffe g; f(&g);/实参为派生类对象的地址 Elephant e; f(&e);/实参为派生类对象的地址观察运行结果#include iostream.hclass Elevoid f(Animal &p)/形参为基类对象的引用p.character(); p.food();void main()Giraffe g; f(g);/实参为派生类对象 Elephant e; f(e);/实参为派生类对象void f(Animal p)/形参为基类对象p.character(); p.food();void main()Giraffe g; f(g);/实参为派
41、生类对象 Elephant e; f(e);/实参为派生类对象若将程序的相应部分修改为如下两种形式,再观察运行结果void f(Animal &p)/形参为基类对象的从上述程序中可见: 只有当虚函数操作的是指向对象的指针或是对象的引用时,对该虚函数调用采取的才是动态联编。虚函数使用说明:派生类中的虚函数应与基类中的虚函数具有相同的名称、参数个数及参数类型。 可以只将基类中的成员函数显式地说明为虚函数,而派生类中的同名函数也隐含为虚函数。从上述程序中可见:派生类中的虚函数应与基类中的虚函数具有相同1.纯虚函数 是一种没有函数体特殊的虚函数,当在基类中不能对虚函数给出有意义的实现,而将其说明为纯虚
42、函数,它的实现留给派生类去做。格式:6.5.4 抽象类 virtual 类型 函数名 (参数表)=0;2. 抽象类 是带有纯虚函数的特殊类,主要作用是将有关的子类组织在一个继承层次结构中,由它来为它们提供一个公共的根。1.纯虚函数6.5.4 抽象类 virtual 类型 函只能用作其它类的基类,不能建立抽象类对象可说明抽象类指针和引用,指向其派生类,进而实现多态性。不能用作参数类型、函数返回类型或强制转换的类型。例6.16抽象类示例程序只能用作其它类的基类,不能建立抽象类对象例6.16抽象类#include #include class baseprotected: int x,y;publi
43、c: virtual void setx(int i,int j=0) x=i; y=j; virtual void disp()=0; ;class square: public basepublic: void disp() coutx*xendl; ;class cube: public basepublic: void disp() coutx*x*xendl; ;class chpow: public basepublic: void disp() coutsetx(5); ptr-disp(); ptr=&C; ptr-setx(6); ptr-disp(); ptr=&D; ptr-setx(3,4); ptr-disp(); 抽象类指针派生类抽象类指针指向不同的派生类对象B、C、D,实现多态性#include class cub6.6 程序举例类名数据成员成员函数vehicle名称含义名称功能wheels车轮个数vehicle初始化数据成员weight车重getwheels、getweight分别获得
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 新版饮用水合同协议书3篇
- 常年性劳务代理协议3篇
- 工程培训设计与施工合同3篇
- 教育培训策划导游劳动合同样本3篇
- 电商运营人员聘用合同书
- 演播室隔音墙施工协议
- 装修合同施工范本
- 矿井排水防涝系统拉管施工合同
- 设备购买协议解除协议
- 印刷行业会计招聘协议样本
- 食品安全检测合作合同
- 养殖场转让写合同范例
- 广东省广州市天河区2023-2024学年高一上学期期末考试数学试卷(解析版)
- 2025年统编版高考政治一轮复习:选择性必修1、2、3共3册必背考点知识点汇编
- 2024社区市民学校工作计划社区市民教育工作计划
- 常见皮肤病与护理
- 安全生产法律法规注册安全工程师考试(初级)试题与参考答案(2024年)一
- 2024年人教版小学六年级上学期期末英语试题与参考答案
- 2024年公文写作基础知识竞赛试题库及答案(共130题)
- 数据管理制度完整
- 医疗组长竞聘
评论
0/150
提交评论