C++ 程序設計教程(第二版):第13章 抽象類_第1頁
C++ 程序設計教程(第二版):第13章 抽象類_第2頁
C++ 程序設計教程(第二版):第13章 抽象類_第3頁
C++ 程序設計教程(第二版):第13章 抽象類_第4頁
C++ 程序設計教程(第二版):第13章 抽象類_第5頁
已閱讀5頁,還剩15頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

14:38:391C++程序設計教程(第二版)第十三章抽象類Chapter13

AbstractClass

14:38:392第十三章內(nèi)容抽象基類(AbstractBase-Class)

抽象類與具體類(Abstract&ConcreteClasses)

深度隔離的界面(InterfaceWhichDeeplyParted)

抽象類作界面(AbstractClassAsInterface)

演繹概念設計(DeductingConceptDesign)

系統(tǒng)擴展(SystemExtension)

手柄(Handle)

14:38:3931.抽象基類(AbstractBase-Class)

繼承體系的多態(tài)問題:繼承體系反映的是事物的分層分類,它是倒樹狀,頂端是基類.越頂端越抽象,越底端越具體.基類往往是一種概念表達,或者像Account類那樣,僅僅提取了各個子類的共性,本身并不構(gòu)成有意義的實體.這種基類的成員都是為子類提供的.特別是虛函數(shù),不同的子類有不同的實現(xiàn),于基類中的定義版本并無意義.classAccount{//...public:virtualvoidwithdrawal(doubleamount){return;//無意義

}};14:38:394虛函數(shù)都是從基類傳播的,靠基類指針來掀動多態(tài).因而,為多態(tài)性之故,非得在基類設置虛函數(shù)不可:

classA{};//基類中無fn()成員classB:publicA{public:

virtual

voidfn();};classC:publicA{public:

virtual

voidfn();};voidf(A*pa){pa->fn();//編譯錯}voidg(){f(&B());f(&C());}14:38:395編譯器的語法規(guī)定,如果一個函數(shù)被調(diào)用了,則該函數(shù)若只有聲明而沒有定義是萬萬不能的

classA{public:

virtualvoidfn();//無定義};classB:publicA{public:

voidfn(){}};classC:publicA{public:

voidfn(){}};voidf(A*pa){pa->fn();//鏈接錯}voidg(){f(&B());f(&C());}14:38:396純虛函數(shù)

classAccount{

//抽象類public:virtualvoidwithdrawal(doubleamount)=0;};Accounta(“3”,30);//錯:創(chuàng)建對象之故前提:不同的子類表現(xiàn)不同的行為——多態(tài),而基類并不產(chǎn)生對象——只是擺設目的:為了安全性,將基類抽象化,僅用來繼承,不準許產(chǎn)生對象.手法:設置純虛函數(shù)。即在基類虛函數(shù)聲明后面加上”=0”,不須提供定義體,表明為抽象類.任何抽象類若有創(chuàng)建對象操作,則是非法的14:38:3972.抽象類與具體類(Abstract&ConcreteClasses)運行下列程序:

voidg(Display*d){d->init();d->write();}intmain(){g(&Monochrome());g(&SVGA());}結(jié)果為:MonochromeColorAdapterclassDisplay{public:

virtualvoidinit()=0;

virtualvoidwrite()=0;};classMonochrome:publicDisplay{

virtualvoidinit(){}

virtualvoidwrite(){cout<<“Monochrome\n”;}};classColorAdapter:publicDisplay{public:

virtualvoidwrite(){cout<<“ColorAdapter\n”;}};classSVGA:publicColorAdapter{public:

virtualvoidinit(){}};如果要解決的問題涉及單一的類對象,無須繼承.如果涉及許多相關的類對象,則需建立一個具有多態(tài)的繼承體系.也許該繼承體系的基類只是用來繼承,別無目的,但抽象基類卻足以將問題中的概念描述清楚.14:38:3983.深度隔離的界面(InterfaceWhichDeeplyParted)

類定義頭文件若有修改,將引起類的實現(xiàn)和類的應用程序重新編譯.

界面不變是指外界可以訪問的公有成員不變,而不是類定義頭文件不變.

類的實現(xiàn)細節(jié)可能涉及私有成員的變更.例如:下列兩個類界面相同,但類定義不同,頭文件自然就不同了.其類的實現(xiàn)也不會相同.日期的年月日版classDate{

intyear,month,day;public:Date(conststring&s);Date(intn=1);Date(inty,intm,intd);Dateoperator+(intn)const;Date&operator+=(intn);Date&operator++();friendostream&operator<<(ostream&o,constDate&d);};日期的天數(shù)版classDate{

intabsDay;public:Date(conststring&s);Date(intn=1);Date(inty,intm,intd);Dateoperator+(intn)const;Date&operator+=(intn);Date&operator++();friendostream&operator<<(ostream&o,constDate&d);};14:38:399設法將界面和類定義分離,來實現(xiàn)深度界面隔離.該類作為界面,便不會影響應用編程classDate{Datemid*m_p;public:Date(conststring&s);Date(intn=1);Date(inty,intm,intd);Dateoperator+(intn)const;Date&operator+=(intn);Date&operator++();friendostream&operator<<(ostream&o,constDate&d);};DateMid類即為以前的Date類:classDateMid{

intyear,month,day;public:DateMid(conststring&s);DateMId(intn=1);DateMid(inty,intm,intd);DateMidoperator+(intn)const;DateMid&operator+=(intn);DateMid&operator++();friendostream&operator<<(ostream&o,constDateMid&d);};14:38:3910界面類的實現(xiàn),便是Date到DateMid的轉(zhuǎn)換#include”date.h”#include”datemid.h”Date::Date(conststrings):m_p(newDateMid(s)){}Date::Date(intn):m_p(newDateMid(n)){}Date::Date(inty,intm,intd):m_p(newDateMid(y,m,d)){}Date::Date(constDateMid&d):m_p(newDateMid(d)){}Date::~Date(){deletem_p;}DateDate::operator+(intn)const{return*m_p+n;}Date&Date::operator+=(intn){*m_p+=n;return*this;}Date&Date::operator++(){*m_p+=1;return*this;}ostream&operator<<(ostream&o,constDate&d){returno<<*(d.m_p);}這樣一來,類DateMid的實現(xiàn)也不影響界面Date.以Date類作為分界線,便可以進行充分的抽象編程了14:38:39114.抽象類作界面(AbstractClassAsInterface)抽象類IDate作界面classIDate{public:virtual~IDate(){}virtualIDate&operator+(intn)=0;virtualIDate&operator+=(intn)=0;virtualIDate&operator++()=0;virtualvoidprint(ostream&o)const=0;};IDate&createDate(inty,intm,intd);IDate&createDate(intn);IDate&createDate(conststrings);inlineostream&operator<<(ostream&o,constIDate&d){d.print(o);returno;}作為界面的Date類轉(zhuǎn)而去調(diào)用DateMid類的對應成員,何不將界面Date類做成抽象類呢?!這樣一來,應用程序可以通過類體系的多態(tài)性來自在使用Date類.另一方面,DateMid的實現(xiàn)可以作為繼承界面類Date的具體類.14:38:3912可以還具體類Date以本來面貌,但這次是從IDate類繼承而來:classDate:publicIDate{

intyear,month,day;public:Date(conststring&s);Date(intn=1);Date(inty,intm,intd);Dateoperator+(intn)const;Date&operator+=(intn);Date&operator++();friendostream&operator<<(ostream&o,constDate&d);};14:38:3913應用編程時,將對象都以指針或引用的方式來操作,而且創(chuàng)建對象的操作由于沒有多態(tài),也需要另外實現(xiàn).將創(chuàng)建對象的工作作成返回對象引用的普通函數(shù),其聲明放在抽象基類的頭文件中,作為界面的一部分.IDate&createDate(inty,intm,intd){

return*newDate(y,m,d);}一旦創(chuàng)建了對象,其他使用對象的操作與原來相同:voidfn(IDate&d){d.print();}intmain(){IDate&rd=createDate(2005,1,6);fn(rd);

delete&rd;}14:38:39145.演繹概念設計(DeductingConceptDesign)抽象編程的要旨是分離各個實現(xiàn)。模塊編程很好地履行了抽象編程的要旨,用名字代表模塊,從而構(gòu)筑程序的框架,之后再實現(xiàn)之,便是從抽象到具體,從上到下的編程方式.用名字構(gòu)架程序結(jié)構(gòu)的抽象編程,實際上是在演繹概念設計.14:38:3915概念設計:

類的繼承體系設計.

界面確定

由于語言的支持,可以直接以代碼設計的形式來進行在概念設計之后進行的工作:程序結(jié)構(gòu)的框架(包括文件組織)實現(xiàn)的環(huán)境和運行方式類代碼設計應用代碼設計14:38:39166.系統(tǒng)擴展(SystemExtension)在類繼承體系中,進行功能擴展的情形主要有兩種:1普遍增加一種操作(在基類中添上純虛函數(shù))2在某個子類中繼承一個非基類第一種情況:可以通過繼承抽象基類的方法,達到功能擴展,維護了應用與類實現(xiàn)的隔離.而又維持了老系統(tǒng)的類繼承體系.SonySony2老系統(tǒng)界面新系統(tǒng)界面14:38:3917第二種情況系統(tǒng)擴展,帶來設施的添加,由于界面不變,所以新設施的編程只是帶來添加部分

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論