9继承和多态 应用和示例

上传人:无*** 文档编号:152056242 上传时间:2022-09-14 格式:PDF 页数:63 大小:636.46KB
收藏 版权申诉 举报 下载
9继承和多态 应用和示例_第1页
第1页 / 共63页
9继承和多态 应用和示例_第2页
第2页 / 共63页
9继承和多态 应用和示例_第3页
第3页 / 共63页
资源描述:

《9继承和多态 应用和示例》由会员分享,可在线阅读,更多相关《9继承和多态 应用和示例(63页珍藏版)》请在装配图网上搜索。

1、继承和多态 应用和示例闫哲闫哲2005年年6月月24日日内容?继承的内存布局继承的内存布局?赋值相容规则赋值相容规则?继承举例继承举例?虚函数实现原理虚函数实现原理?多态性举例多态性举例?设计模式设计模式继承的内存布局?通过继承,派生类中包含基类成员通过继承,派生类中包含基类成员class Point2dpublic:Point2d()/protected:float x,y;class Point3d:public Point2dpublic:Point3d():Point2d()/private:float z;Point3d obj2;Point2d obj1;float xfloat

2、yfloat zfloat xfloat y基类成员基类成员private:构造函数和析构函数的调用顺序构造函数和析构函数的调用顺序访问权限的理解访问权限的理解继承的内存布局?对比:对象成员对比:对象成员class Point2dpublic:Point2d()/protected:float x,y;class Point3d:public:Point3d():point()/private:Point2d point;float z;Point3d obj2;Point2d obj1;float xfloat yfloat zfloat xfloat ypoint对象成员对象成员赋值相同规

3、则?通过公有继承,派生类的对象可以当作基类使用通过公有继承,派生类的对象可以当作基类使用class Point2dpublic:void show();protected:float x,y;class Point3d:public Point2dpublic:void show();private:float z;void main()Point2d obj2d;Point3d obj3d;obj2d=obj3d;/对象赋值对象赋值obj2d.show();/调用调用Point2d:show()Point3d obj3d;Point2d obj2d;float xfloat yfloat z

4、float xfloat y派生类对象赋值给基类对象派生类对象赋值给基类对象向上映射、对象切片向上映射、对象切片赋值相同规则?通过公有继承,派生类指针可以赋给基类指针通过公有继承,派生类指针可以赋给基类指针class Point2dpublic:void show();protected:float x,y;class Point3d:public Point2dpublic:void show();private:float z;void main()Point2d obj2d;Point3d obj3d;Point3d obj3d;Point2d obj2d;p3dp2dfloat xfl

5、oat yfloat zfloat xfloat yp2d/指针赋值指针赋值Point2d*p2d=&obj2d;Point3d*p3d=&obj3d;p2d=p3d;p2d-show();调用调用Point2d:show()多重继承的内存布局?通过多重继承,派生类中包含各基类成员通过多重继承,派生类中包含各基类成员class Point2dpublic:/protected:float x,y;class Point3d:public Point2dpublic:/protected:float z;class Vertexpublic:/protected:Vertex*next;clas

6、s Vertex3d:public Point3d,public Vertexpublic:/protected:float mumble;Point2dPoint3dVertex3dVertex多重继承的内存布局float xfloat yfloat zVertex*nextfloat xfloat yfloat zPoint2d子对象子对象Point3d子对象子对象Point2d子对象子对象Vertex子对象子对象Point3d obj1;float mumbleVertex*nextVertex3d obj3;Vertex obj2;/对象赋值对象赋值obj1=obj3;obj2=obj

7、3;/指针赋值指针赋值Point3d*p3d=&obj3;Vertex*pv=&obj3;/涉及指针偏移涉及指针偏移赋值相容规则:赋值相容规则:多重继承的内存布局?多重继承中数据成员的二义性多重继承中数据成员的二义性int memberint memberint total来自base1class base1protected:int member;public:base1()/;class base2protected:int member;public:base2()/;class derived:public base1,public base2private:int total;pub

8、lic:derived()/void func()member=0;/二义性;来自base2derived对象布局base1:member=0;base2:member=0;多重继承的内存布局?虚拟基类之前的内存布局虚拟基类之前的内存布局int bint b2class baseprotected:int b;class base1:public baseprotected:int b1;class base2:public baseprotected:int b2;class derived:public base1,public base2float d;public:int fun();

9、int bint b1base2的内存布局的内存布局base1的内存布局的内存布局int bint b1int bint b2float d二义性二义性derived的内存布局的内存布局不能把不能把derived对象当对象当base对象使用对象使用多重继承的内存布局通过指针指向共享的虚拟基类通过指针指向共享的虚拟基类?虚拟基类的内存布局虚拟基类的内存布局int b2int bclass baseprotected:int b;class base1:virtual public baseprotected:int b1;class base2:virtual public baseprotec

10、ted:int b2;class derived:public base1,public base2float d;public:int fun();int b1int bbase*pbase*pbase1的内存布局的内存布局base2的内存布局的内存布局int b1int b2float dint bbase*pbase*pderived的内存布局的内存布局可以把可以把derived对象当对象当base对象使用对象使用继承的使用?从现实中捕获一般从现实中捕获一般-特殊关系特殊关系class Automobilepublic:Automobile();void start();void sto

11、p();void speedup();void speeddown();protected:char*brand;float price;float speed;class Car:public Automobilepublic:Car();void absstop();private:float gas_comsume;class Jeep:public Automobilepublic:Jeep();void climb();private:int drive;class Truck:public Automobilepublic:Truck();void transport();priv

12、ate:float load;AutomobileCarJeepTruck继承的使用?从相似的类中提取共同的特征,形成类层次从相似的类中提取共同的特征,形成类层次在银行业务中,有储蓄在银行业务中,有储蓄(Saving)账户和结算账户和结算(Checking)账户之分,两个类的设计:账户之分,两个类的设计:SavingaccNumberbalanceSaving()Withdraw()Deposit()Display()CheckingaccNumberbalanceremittanceChecking()Withdraw()Deposit()Display()SetRemit()Consume

13、()储蓄账户储蓄账户结算账户结算账户继承的使用/类的定义省略#includeSaving:Saving(int accNo,float bal=0)accNumber=accNo;balance=bal;void Saving:Withdraw(float bal)if(bal0)balance-=bal;void Saving:Deposit(float bal)if(bal0)balance+=bal;void Saving:Display()cout“Saving Account”accNo“:”balanceendl;Checking:Checking(int accNo,float

14、bal=0)accNumber=accNo;balance=bal;void Checking:Withdraw(float bal)float tmp;/根据remit值计算tmpif(tmp0)balance-=tmp;void Checking:Deposit(float bal)if(bal0)balance+=bal;void Checking:Display()cout“Saving Account”accNo“:”balanceendl;void Checking:SetRemit(int rem)remittance=rem;void Checking:Consume(floa

15、t price,float add=0)float tmp=price+add;if(tmp0)balance-=tmp;继承的使用?Checking类继承类继承Saving类类SavingaccNumberbalanceSaving()Withdraw()Deposit()Display()CheckingremittanceChecking()Withdraw()SetRemit()Consume()储蓄账户储蓄账户结算账户结算账户继承的使用class Savingprotected:int accNumber;float balance;public:Saving(int accNo,f

16、loat bal=0);void Withdraw(float bal);void Deposit(float bal);void Display();class Checking:public Savingprivate:int remittance;public:Checking(int accNo,float bal=0);void Withdraw(float bal);void setRemit(int rem);void Consume(float price,float add);#include/Saving的实现Checking:Checking(int accNo,floa

17、t bal=0):Saving(accNo,bal)void Checking:Withdraw(float bal)float tmp;/根据remit计算if(tmp0)balance-=tmp;void Checking:setRemit(int rem)remittance=remit;Void Checking:Consume(float price,float add=0)float tmp=price+add;if(tmp0)balance-=tmp;继承的使用?思考继承关系:结算帐户思考继承关系:结算帐户 is-a 储蓄帐户吗?储蓄帐户吗?SavingChecking增加数据成

18、员增加数据成员overdraft表示透支范围表示透支范围在在Withdraw()中允许透支中允许透支则则Checking也得到了该数据成员也得到了该数据成员其实,其实,Checking不是一种不是一种Saving,而是不同类型的两种帐户而是不同类型的两种帐户AccountaccNumberbalanceAccount()Withdraw()Deposit()Display()SavingoverdraftSaving()Withdraw()CheckingremittanceChecking()Withdraw()setRemit()Consume()继承的使用class Accountpro

19、tected:int accNumber;float balance;public:Account(int accNo,float bal=0);virtual void Withdraw(float bal);void Deposit(float bal);void Display();class Saving:public Accountprivate:float overdraft;public:Saving(int accNo,float bal=0):Account(accNo,bal)void Withdraw(float bal);class Checking:public Ac

20、countprivate:int remittance;public:Checking(int accNo,float bal=0):Account(accNo,bal)void Withdraw(float bal);void setRemit(int remit);void Consume(float price,float add);virtual void Withdraw(float bal)=0;Account、Saving、Checking之间的层次关系符合现实之间的层次关系符合现实Saving和和Checking可独立变化可独立变化继承的使用?现实世界中的类层次现实世界中的类层

21、次PersonStudentTeacherCollegeStudentGraduateStudentInstructorProfessorGoodsBookMusicMovieComputerEconomicsLiteraturepopularclassiccartoon继承的使用?现实世界中的类层次现实世界中的类层次EmployeeManagerStaffConsultantFulltime ParttimeProductFruitDairyMeetMilkButterPorkBeefAppleWaterm价格调整策略:价格调整策略:数据成员数据成员supply和和demand成员函数成员函

22、数pricechange()不同商品计算价格变动不同商品计算价格变动继承的使用?纸牌游戏问题纸牌游戏问题?设计设计CardGame类用来表示普通的类用来表示普通的52张纸牌,有四种花色张纸牌,有四种花色(红心红心/方块方块/梅花梅花/黑桃黑桃),各,各13张,用适当的方式实现纸牌的基本功能。张,用适当的方式实现纸牌的基本功能。?从从CardGame类派生出类派生出Bridge类,为类,为Bridge类设计类设计deal函数,用来将纸牌分给函数,用来将纸牌分给4人,每人人,每人13张;张;?从从CardGame类派生出类派生出Poker类,为类,为Poker类设计类设计deal函数,用来将纸牌分

23、给函数,用来将纸牌分给n(27)人,每人人,每人5张。张。?最后编写测试程序。最后编写测试程序。CardGameBridgePoker继承的使用enum CardTypeHeart,Diamond,Club,Spade;/红心、方块、梅花、黑桃struct CardCardType type;int no;class CardGameprotected:Card cards52;int remain;/发牌后剩余张数int persons;/玩牌人数void showCard(Card);public:CardGame(int p_num=4);void wash();void deal();

24、void display();class Bridge:public CardGamepublic:Bridge();void deal();class Poker:public CardGamepublic:Poker(int p_num=4);void deal();继承的使用void CardGame:wash()/洗牌Card temp52;for(int i=0;i52;i+)tempi=cardsi;for(i=0;i52;i+)int location=(int)(52*rand()/(float)RAND_MAX);while(!templocation.no)location

25、=(int)(52*rand()/(float)RAND_MAX);cardsi=templocation;templocation.no=0;remain=52;void CardGame:showCard(Card c)cout(char)(c.type+3)1&c.no11)coutc.no;else if(c.no=1)coutA;else if(c.no=11)coutJ;else if(c.no=12)coutQ;else if(c.no=13)coutK;#include#include#includeCardGame.h“CardGame:CardGame(int p_num)

26、for(int i=0;i4;i+)/CardTypefor(int j=0;j13;j+)/CardNocardsi*13+j.type=(CardType)i;cardsi*13+j.no=j+1;remain=52;persons=p_num;void CardGame:display()cout=Cards=endl;for(int i=0;i52;i+)showCard(cardsi);if(i+1)%13=0)coutendl;cout=Cards=endl;继承的使用void Poker:deal()if(remainpersons*5)/先检查是否够发cout余牌不足,请重新洗

27、牌!endl;return;for(int i=0;ipersons;i+)coutPersoni+1:endfor(int j=0;j5;j+)showCard(cards52-remain+j*persons+i);coutendl;/for personsremain=remain-5*persons;void main()Bridge b_game;b_game.display();b_game.wash();b_game.deal();Poker p_game(5);p_game.wash();p_game.display();p_game.deal();p_game.deal();

28、Bridge:Bridge()void Bridge:deal()coutFirst Person:endl;for(int i=0;i13;i+)showCard(cardsi*4);coutendl;coutSecond Person:endl;for(i=0;i13;i+)showCard(cardsi*4+1);coutendl;coutThird Person:endl;for(i=0;i13;i+)showCard(cardsi*4+2);coutendl;coutFourth Person:endl;for(i=0;i13;i+)showCard(cardsi*4+3);cout

29、endl;remain=0;Poker:Poker(int p_num):CardGame(p_num)虚函数原理?虚函数表虚函数表vtbl及其指针及其指针vptrPoint的内存布局的内存布局class Pointpublic:virtual Point();virtual Point&mult(float)=0;float x()return _x;virtual float y()return 0;virtual float z()return 0;protected:Point(float x=0.0);float _x;_xvptr_Pointtype_info for Point#

30、0#1#2#3#4Point:Point()纯虚函数纯虚函数Point:y()Point:z()虚拟表虚拟表vtable虚函数原理?派生类覆盖定义虚函数派生类覆盖定义虚函数class Point2d:public Pointpublic:Point2d(float xf=0.0,float yf=0.0):Point(xf)_y=yf;Point2d();Point2d&mult(float);float y()return _y;protected:float _y;虚拟表虚拟表vtablePoint2d的内存布局的内存布局type_info for Point2d_xvptr_Point_

31、y#0#1#2#3#4Point2d:Point2d()Point2d:mult(float)Point2d:y()Point:z()虚函数原理?派生类覆盖定义虚函数派生类覆盖定义虚函数class Point3d:public Point2dpublic:Point3d(float xf=0.0,float yf=0.0,float zf=0.0):Point2d(xf,yf)_z=zf;Point3d();Point3d&mult(float);float z()return _z;protected:float _z;虚拟表虚拟表vtablePoint3d的内存布局的内存布局type_in

32、fo for Point3d_xvptr_Point_y_z#0#1#2#3#4Point3d:Point3d()Point3d:mult(float)Point2d:y()Point3d:z()虚函数原理?通过基类指针或引用调用虚函数通过基类指针或引用调用虚函数_xvptr_yvoid main()Point2d obj2d;Point3d obj3d;Point*p=&obj2d;coutz();p=&obj3d;coutz();Point2d虚拟表虚拟表vtabletype_info for Point2d#0Point2d:Point2d()#1Point2d:mult(float)#

33、2obj2dPoint2d:y()#3Point:z()#4p-z();转化成转化成(*p-vptr4)(p);type_info for Point3dPoint3d:Point3d()Point3d:mult(float)Point2d:y()Point3d:z()Point3d虚拟表虚拟表vtable#0#1#2#3#4_xvptr_yobj3d_z虚函数原理?通过基类对象调用虚函数?静态联编通过基类对象调用虚函数?静态联编/假设修改假设修改Point定义:定义:/去掉纯虚函数,改为公有构造去掉纯虚函数,改为公有构造void main()Point obj;Point2d obj2d;o

34、bj=obj2d;/静态联编静态联编coutobj.y();Point*p=&obj;couty();/动态联编动态联编x_Point2dy_Point2dx_Pointobjobj2dvptr_Pointvptr_Point2dPoint虚拟表虚拟表x_Point2dvptr_Pointvtbl赋值后的赋值后的obj虚函数原理?非虚函数的调用?静态联编非虚函数的调用?静态联编/假设假设Point增加非虚函数增加非虚函数Show()/Point2d和和Point3d分别覆盖定义分别覆盖定义void main()Point2d obj2d;Point*p=&obj2d;p-show();x_Po

35、int2dy_Point2dobj2dvptr_Point2dpp-show()进行静态联编进行静态联编(*p).show();虚函数原理?派生类要覆盖定义虚函数派生类要覆盖定义虚函数type_info1#includeclass Basepublic:virtual void fn(int x)cout“In Base Class,x=”xendl;class Derived:public Basepublic:void fn(float x)cout“In Derived Class,x=”xendl;void test(Base&b)int i=1;b.fn(i);float f=2.0

36、;b.fn(f);vptrBase:fnBase对象对象Base的vtblvptrBase:fnDerived对象对象type_info2Derived的vtbl没有覆盖定义没有覆盖定义虚函数原理?同名函数分类:同名函数分类:?重载(重载(overload):相同作用域内名字相同参数不同):相同作用域内名字相同参数不同?覆盖、改写(覆盖、改写(override):派生类中覆盖定义):派生类中覆盖定义?隐藏(隐藏(hide):内部作用域中屏蔽外部同名函数):内部作用域中屏蔽外部同名函数#includeclass basepublic:virtual void f()cout“base:f”end

37、l;virtual void f(int a)cout“base:f-”aendl;class derived:public basepublic:virtual void f(float b)cout“derived:f-”bendl;void main()derived d;d.f(5);/调用derived:f(float)d.f();/错误,base中的f()被隐藏了虚函数原理?注意继承类层次中虚函数的位置注意继承类层次中虚函数的位置class Apublic:virtual void f();void g();protected:int a;class B:public Apubli

38、c:void f();virtual void g();virtual void h();protected:int b;void test1(A&ref)ref.f();ref.g();/静态联编A:g()type_info_Aint aA:f()vptr_AA的的vtblA对象对象vptr_Atype_info_BB:f()vptr_BB对象对象int aint btype_info_B来自来自A的的vtblB:f()B:g()B的的vtblB:h()多态性的使用?虚析构函数的作用虚析构函数的作用#includeclass Baseprotected:char*p;public:Base(

39、)p=new char5;Base()delete p;cout“Base()fired”endl;class Derived:public Baseprivate:char*q;public:Derived()q=new char100;Derived()delete p;cout“Derived fired”endl;void main()Base*p=new Derived;delete p;/调用Base()Derived中中q指向的空间没有释放掉指向的空间没有释放掉将将Derived设为虚析构函数设为虚析构函数virtual Base()多态性的使用?弹奏不同乐器弹奏不同乐器play

40、(note)InstrumentWindString#includeenum notemiddleC,Csharp,Cflat;class Instrumentpublic:virtual void play(note)cout“Instrument:play”endl;class Wind:public Instrumentpublic:void play(note)cout“Wind:play”endl;class String:public Instrumentpublic:void play(note)cout“String:play”endl;void tune(Instrument

41、&i)i.play(middleC);void main()Wind wobj;String sobj;tune(wobj);tune(sobj);多态性的使用?多态性便于扩展多态性便于扩展class Percussion:public Instrumentpublic:void play(note)cout“Percussion:play”endl;class Brass:public Windpublic:void play(note)cout“Brass:play”endl;void tune(Instrument&i)/不变void main()Percussion pobj;tune

42、(pobj);Brass bobj;tune(bobj);play(note)InstrumentWindStringPercussionBrass使用方式:在外部函数中调用虚函数,使用方式:在外部函数中调用虚函数,传入基类引用或指针传入基类引用或指针多态性的使用?通过指向基类的指针数组记录数据通过指向基类的指针数组记录数据编写同时管理整数和字符串的程序,要求输出这些数据编写同时管理整数和字符串的程序,要求输出这些数据ElementMyIntegerMyStringshowMe()#includeclass Elementpublic:virtual void showMe()=0;class

43、 MyInteger:public Elementprivate:int num;public:MyInteger(int=0);virtual void showMe()cout“MyInteger-”numendl;class MyString:public Elementprivate:char*p;public:MyString(char*=“”);void showMe()cout“MyString-”pendl;void main()Element*list10;/准备list中的数据for(int i=0;ishowMe();多态性的使用?在在main函数中根据用户选择创建不同类

44、型对象函数中根据用户选择创建不同类型对象#includeclass TradesPersonpublic:virtual void sayHi()cout“Just hi.”endl;class Tailor:public TradesPersonpublic:void sayHi()cout“Hi,can I make clothes for you?”endl;class Barber:public TradesPersonpublic:void sayHi()cout“Hi,have you cut hair today?”endl;void main()TradesPerson*p;i

45、nt op;do coutop;while(op3);switch(op)case 1:p=new TradesPerson;break;case 2:p=new Tailor;break;case 3:p=new Barber;break;p-sayHi();delete p;多态性的使用?图形编辑器图形编辑器-典型多态使用场合典型多态使用场合class Shapepublic:virtual void draw();virtual bool inShape(int,int);class Line:public Shapepublic:void draw();bool inShape(int

46、,int);private:int s_x,s_y,e_x,e_y;class Rectangle:public Shapeclass Circle:public Shape设计模式?设计模式的产生设计模式的产生?复用的重要性复用的重要性?大侠和菜鸟大侠和菜鸟经验值经验值?模式的思想模式的思想?经验如何复用?设计模式经验如何复用?设计模式 or 软件框架软件框架设计模式:将面向对象软件设计的经验记录下来设计模式:将面向对象软件设计的经验记录下来?设计模式的作用设计模式的作用?使人们可以更简单方便的复用成功的设计和体系结构使人们可以更简单方便的复用成功的设计和体系结构?帮助开发人员做出有利于系统

47、复用的选择帮助开发人员做出有利于系统复用的选择?增加系统的灵活性和可维护性增加系统的灵活性和可维护性设计模式?设计模式:可复用面向对象软件的基础设计模式:可复用面向对象软件的基础?Design Patterns:Elements of Reusable Object-Oriented software?Erich Gamma等等4人,人,GoF设计模式?设计模式的定义设计模式的定义?每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次的使用该方案而不必作重复劳动。每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就

48、能一次又一次的使用该方案而不必作重复劳动。(Christopher Alexander)?模式是对反复出现的问题的一种通用解决方案,它是经过实践验证的模式是对反复出现的问题的一种通用解决方案,它是经过实践验证的?学习设计模式学习设计模式?设计模式的描述设计模式的描述?名称:助记名名称:助记名?问题:在何时使用该模式问题:在何时使用该模式?解决方案:设计的组成成分,它们之间的相互关系及各自的职责和协作方式解决方案:设计的组成成分,它们之间的相互关系及各自的职责和协作方式?效果:模式应用的效果和使用模式应权衡的问题效果:模式应用的效果和使用模式应权衡的问题设计模式?设计模式解决设计问题的原则设计模

49、式解决设计问题的原则?寻找合适的对象寻找合适的对象对象根据分析确定,抽象原则对象根据分析确定,抽象原则?确定对象粒度确定对象粒度?指定对象接口指定对象接口针对接口编程针对接口编程?描述对象实现描述对象实现?运用复用机制运用复用机制组合和继承组合和继承?设计应支持变化设计应支持变化问题分离原则、高内聚低耦合问题分离原则、高内聚低耦合?封装创建对象的过程封装创建对象的过程Factory?封装特殊的操作封装特殊的操作Command?封装算法封装算法Strategy?封装修改动作封装修改动作Adapter设计模式?继承类层次?多态继承类层次?多态BaseDerived1Derived2Base*p1=

50、new Derived1;Base*p2=new Derived2;类的使用者需要知道子类的名称类的使用者需要知道子类的名称程序的扩展性和维护变得困难程序的扩展性和维护变得困难父类中不知道具体实例化哪一个具体的子类父类中不知道具体实例化哪一个具体的子类ABConcrete1Concrete2(抽象类抽象类)设计模式?对象创建的过程可能发生变化?封装对象创建的过程可能发生变化?封装?Factory模式模式设计模式?使得实例化类的工作已到子类中使得实例化类的工作已到子类中?Factory Method模式模式定义一个用于创建对象的接口定义一个用于创建对象的接口(Factory),让子类决定实例化哪

51、一个类。,让子类决定实例化哪一个类。虚构造器:将构造产品类的操作延迟到工厂的子类中虚构造器:将构造产品类的操作延迟到工厂的子类中ApplicationDocument设计模式#includeclass Product public:virtual Product()=0;protected:Product();class ConcreteProduct:public Product public:ConcreteProduct()cout“ConcreteProduct”;ConcreteProduct();class Factory public:virtual Factory()=0;vi

52、rtual Product*CreateProduct()=0;protected:Factory();class ConcreteFactory:public Factory public:ConcreteFactory()coutCreateProductA();cf1-CreateProductB();AbstractFactory*cf2=new ConcreteFactory2();cf2-CreateProductA();cf2-CreateProductB();设计模式?可能遇到接口不一致的情况可能遇到接口不一致的情况驾驶驾驶A不会驾驶不会驾驶Team客户客户B会驾驶会驾驶Tea

53、mAB驾驶驾驶TeamAC驾驶驾驶B向向B学习学习设计模式?Adapter适配器模式适配器模式?将一个类的接口转换成客户希望的另外一个接口将一个类的接口转换成客户希望的另外一个接口?使得原本由于接口不兼容而不能一起工作的类能一同工作使得原本由于接口不兼容而不能一起工作的类能一同工作包装器包装器Wrapper类适配器类适配器适用:要使用一个已经存在的类(类库),但其接口不符合需求适用:要使用一个已经存在的类(类库),但其接口不符合需求设计模式class Target public:Target()virtual void Request();class Adaptee public:Adapte

54、e()void SpecificRequest();class Adapter:public Target,private Adaptee public:Adapter()void Request();#includevoid Target:Request()coutTarget:Request;void Adaptee:SpecificRequest()coutSpecificRequest();void main()Target*t=new Adapter;t-Request();设计模式?Adapter适配器模式适配器模式?对象适配器:通过包含已有类来获得服务对象适配器:通过包含已有类来

55、获得服务?适用于无法进行继承的情况适用于无法进行继承的情况(单一继承、源代码限制单一继承、源代码限制)比较:比较:Adapter可以重新定义可以重新定义Adaptee的行为的行为类适配器:类适配器:对象适配器:对象适配器:Adapter可以与多个可以与多个Adaptee一同工作一同工作设计模式#includevoid Target:Request()coutTarget:Requestendl;void Adaptee:SpecificRequest()coutAdaptee:SpecificRequest_ade=ade;void Adapter:Request()_ade-Specific

56、Request();void main()Adaptee*ade=new Adaptee;Target*adt=new Adapter(ade);adt-Request();class Target public:Target()virtual void Request();class Adaptee public:Adaptee()void SpecificRequest();class Adapter:public Target public:Adapter(Adaptee*ade);void Request();private:Adaptee*_ade;设计模式?可能需要统一处理单个对象

57、和组合对象可能需要统一处理单个对象和组合对象单个图形单个图形:Line、Rectangle组合图形:组合图形:Person单个图形单个图形组合图形组合图形区别对待?区别对待?图形编辑器图形编辑器单个图形单个图形组合图形组合图形设计模式?Graphic基类既代表单个图形,又代表组合图形基类既代表单个图形,又代表组合图形两种图形可以一致对待两种图形可以一致对待设计模式?Composite组合模式组合模式?将对象组合成树形结构以表示将对象组合成树形结构以表示“部分部分-整体整体”的层次结构的层次结构?使得用户对单个对象和组合对象的使用具有一致性使得用户对单个对象和组合对象的使用具有一致性适用:想表示

58、对象的整体适用:想表示对象的整体-部分层次结构部分层次结构希望忽略单个对象和组合对象的不同希望忽略单个对象和组合对象的不同设计模式class Component public:Component();public:virtual void Operation()=0;virtual void Add(const Component&)virtual void Remove(const Component&)virtual Component*GetChild(int);Component*Component:GetChild(int)return NULL;class Leaf:public

59、Component public:Leaf()void Operation();#includevoid Leaf:Operation()cout“Leaf Operation”endl;设计模式#includeclass Composite:public Component public:Composite()public:void Operation();void Add(Component*com);void Remove(Component*com);Component*GetChild(int index);private:vector comVec;void Composite:O

60、peration()vector:iteratorcomIter=comVec.begin();for(;comIter!=comVec.end();comIter+)(*comIter)-Operation();void Composite:Add(Component*com)comVec.push_back(com);void Composite:Remove(Component*com)comVec.erase(&com);Component*Composite:GetChild(int index)return comVecindex;void main()Leaf*lf=new Le

61、af();lf-Operation();Composite*com=new Composite();com-Add(lf);com-Add(new Leaf();com-Operation();Component*c=com-GetChild(0);c-Operation();作业?改写改写CardGame类,实现多态调用类,实现多态调用?设计一个类层次,其中的基类为设计一个类层次,其中的基类为Date,它有一个虚函数它有一个虚函数print(输出输出6-22-2004形式形式);从从Date派生派生ShortE类类(print输出输出22-6-2004形式形式)、MediumDate类类(p

62、rint输出输出Jun.22,2004)和和LongDate类类(print输出输出June 22,2004);并且编写并且编写main函数进行测试。函数进行测试。?网络管理软件中,存在抽象基类网络管理软件中,存在抽象基类Host,其中含有纯虚成员函数,其中含有纯虚成员函数poll:virtual HostInfo&poll()=0其中其中HostInfo包含主机的各种信息包含主机的各种信息(ip地址地址/主机类型主机类型/上网时间上网时间/状态等状态等)。从从Host派生出派生出WorkStation、FileServer、PC,每个类都覆盖,每个类都覆盖poll函数,函数,用来返回与派生类相关的信息。编写一个测试程序,其中包含下面的代码用来返回与派生类相关的信息。编写一个测试程序,其中包含下面的代码段:段:for(int i=0;ipoll();

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