面向?qū)ο蟪绦蛟O(shè)計理論_第1頁
已閱讀1頁,還剩79頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、1,一、面向?qū)ο蟪绦蛟O(shè)計理論,,1.1 面向?qū)ο蟮某绦蛟O(shè)計方法基礎(chǔ),1.2 對象和類,1.3 繼承性,1.4 重載,1.5 多態(tài)性,2,1.1 OOP基礎(chǔ),,面向?qū)ο蟮某绦蛟O(shè)計方法(Object Oriented Programming)簡稱為OOP,它的基本元素是類(Class)和對象(Object)。,使用對象模擬自然的或抽象的實(shí)體,對用戶掩蓋了實(shí)現(xiàn)的復(fù)雜性(封裝),并且能使程序員付出盡可能小的代價,獲得盡可能大收益(繼承),提高軟

2、件的開發(fā)效率。,3,1.2 對象和類,,類是對事物的特性及操作的抽象描述,對象是類的實(shí)體。,從C語言的角度來看,類是結(jié)構(gòu)的自然演化,類就是包含數(shù)據(jù)聲明和函數(shù)聲明的結(jié)構(gòu)。,類既包含了數(shù)據(jù)又包含了代碼,對類中成員的存取是受控制的,這一控制不僅針對數(shù)據(jù),也針對代碼,類的這個特性被稱為封裝。,4,,計算過程的演變: 手工計算  全部手工和腦力完成 計算器(面向過程)  部分借助非人力因素,但仍需對過程進(jìn)行控制和管理 計算機(jī)(面向?qū)ο螅?/p>

3、  完全借助非人力因素,運(yùn)算一旦開始,可以無需人工的介入,封裝的說明,5,,特性:  腳個數(shù)  物理位置  長度  寬度  高度  形狀,操作:  搬動  改造,類的說明,,,,,,,,,,“桌子”類,6,,定義類,,class Counter { long count;public: void SetValue(long); long GetValue();};,關(guān)鍵字clas

4、s引導(dǎo)類聲明,Counter是類標(biāo)識符,類體,分號,7,,,使用類,類是一個模板,就象數(shù)據(jù)類型一樣,使用的時候必須定義類變量。定義類變量稱為類的實(shí)例化,類的實(shí)例化變量就是對象。,void main (){ Counter people; long value; people.SetValue(0); value = people.GetValue();},對象是具有某一個

5、類所描述的共性的,但又有各自特性的個體。,8,類存取控制,,類的成員的使用者有三類:1. 類本身2. 一般用戶3. 派生類每種使用者權(quán)限不同,對應(yīng)與不同的使用權(quán)限,有不同的關(guān)鍵字說明。,9,類私有成員(private),,類本身(或類的友元)可以存取類的私有成員。派生類不能存取其父類的私有成員。  因?yàn)轭惐仨氃诔绦蛑惺褂?,所以類必須至少有一個非私有的成員。  類成員的存取控制缺省為私有類型。,10,類私有成員

6、(續(xù)),,,class PrivateClass { long value; void f1(); void f2();};,void main(){ PrivateClass object; long l = object.value; object.f1(); object.f2();},提問:上述程序可以達(dá)到預(yù)期效果嗎?,類私有成員(續(xù)),11,類公有成員(public

7、),,在程序中使用給定類的對象,必須能存取成員數(shù)據(jù)、成員函數(shù)或兩者。  為使這些成員在程序中可以被存取,必須在類中聲明公有部分?! ≡诠胁糠侄x的內(nèi)容允許被其他對象無限制地存取。通常可以有控制地使用公有成員存取私有數(shù)據(jù),調(diào)用私有成員函數(shù)完成工作。,12,類公有成員(續(xù)),class PublicExample{public: int variable; void function();};,void m

8、ain(){ PublicExample object; int i = object.variable; object.function();},,13,類保護(hù)成員(protected),,class A {protected: int value_a; };class B:public A { public: void FB();};class C:public B{

9、 public: void FC();},void B::FB(){ value_a = 0;}void C::FC(){ value_a = 0},14,問題,,class A { int value_1;protected: int value_2; void FA_1();public: int value_3; void FA_2();};,

10、class B:public A{public: int value_4; void FB();},問:在類B的FB函數(shù)中可以直接存取的成員有哪些?問:通過類B的對象在程序中可以直接訪問的成員有哪些?,15,特殊類成員,,特殊類成員,1、構(gòu)造函數(shù)(constructor),2、析構(gòu)函數(shù)(destructor),16,構(gòu)造函數(shù),,構(gòu)造函數(shù)是用來建立某給定類的對象的。一個類可以不定義構(gòu)造函數(shù),也可以定義一個或多個構(gòu)造函

11、數(shù)。編譯系統(tǒng)保證類的構(gòu)造函數(shù)先于其他函數(shù)被調(diào)用。,17,構(gòu)造函數(shù)(續(xù)一),,class Counter {long value;public:Counter();};Counter::Counter(){value = 100;},void main(){Counter c1;return;},構(gòu)造函數(shù)Counter()它有什么特點(diǎn)?,18,構(gòu)造函數(shù)(續(xù)二),,class Counter {

12、long value;public: Counter();};Counter::Counter(int i){ value = i;},void main(){ Counter c1(100); return;},構(gòu)造函數(shù)Counter()它有什么特點(diǎn)?,19,構(gòu)造函數(shù)(續(xù)三),,class Counter { long value;public: Counter()

13、 Counter(int i);};Counter::Counter(){ value = 100;},Counter::Counter(int i){ value = i;}void main(){ Counter c1; Counter c2(100); return;},20,構(gòu)造函數(shù)(續(xù)四),class Counter { long value;publi

14、c: Counter() { value = 100; } Counter(int i = 0) { value = i;}};void main() { Counter c1; Counter c2(100);},,問:Counter類是否能包含如上所示的兩個構(gòu)造函數(shù)?為什么?,21,構(gòu)造函數(shù)(續(xù)五),,class Counter { long value;public: C

15、ounter(Counter &)};Counter::Counter(Counter & reference){ value = reference.value;},22,,void main() { Counter object(5); Counter object1 = object;};,構(gòu)造函數(shù)(續(xù)六),這個等號表示復(fù)制構(gòu)造函數(shù),void main() { Counte

16、r object(5); Proc_A(object);};,把對象作為參數(shù)傳遞,也需要拷貝構(gòu)造函數(shù)。,23,構(gòu)造函數(shù)(小結(jié)一),1、缺省構(gòu)造函數(shù),2、有特定初始化值的構(gòu)造函數(shù),3、通過復(fù)制另一個對象建立新對象的構(gòu)造函數(shù),,24,構(gòu)造函數(shù)(小結(jié)二),1、構(gòu)造函數(shù)沒有返回類型,2、構(gòu)造函數(shù)與類同名,3、同一個類可以有多個構(gòu)造函數(shù),,25,構(gòu)造函數(shù)(思考題),,class Counter { long value;pub

17、lic: Counter();};class Example { int value;public: Counter c; Example();};,void main(){ Example e;},在本例中,當(dāng)c對象作為e對象的成員。問:c對象和e對象的構(gòu)造函數(shù)的調(diào)用順序是怎樣的?,26,析構(gòu)函數(shù),,析構(gòu)函數(shù)在對象不再被使用時,執(zhí)行一些必須的操作,一般是構(gòu)造函數(shù)的逆操作。一個類只

18、能聲明一個析構(gòu)函數(shù)?! ∥鰳?gòu)函數(shù)是構(gòu)造函數(shù)的逆函數(shù)。,27,析構(gòu)函數(shù)(續(xù)),,class Counter { long value;public: ~Counter();};Counter::~Counter(){ printf(“…”);},析構(gòu)函數(shù)在聲明和使用上有什么特點(diǎn)?,28,析構(gòu)函數(shù)(小結(jié)),,1、析構(gòu)函數(shù)沒有返回類型,2、析構(gòu)函數(shù)的命名是在類名前加“~”,3、一個類只能有一個析構(gòu)函數(shù),4、

19、析構(gòu)函數(shù)沒有參數(shù),29,1.3 繼承性,,從編碼角度講,從基類中派生類以較低代價換來了大量的靈活性。一旦產(chǎn)生了可靠的基類,只需要調(diào)試派生類中所做的修改即可?! ∨缮悘乃母割愔欣^承性質(zhì)時,可使派生類對它們進(jìn)行擴(kuò)展、限制、改變、刪除或不做任何修改。所有這些變化歸結(jié)成兩類基本的面向?qū)ο蠹夹g(shù):性質(zhì)約束和性質(zhì)擴(kuò)展。,30,單一繼承,,class First { int value_1;protected: int valu

20、e_2;public: int value_3;};,class Second:First{ int value_4;public: void F2();};,問:在程序中可以訪問的Second類的對象的成員變量有那些?,31,基類存取限定符,class First { int value_1;protected: int value_2;public: int value_3

21、;};,class Second:public First{ int value_4;public: void F2();};,基類存取限定符,,32,基類存取限定符(續(xù)),,private:如果沒有特別說明,private是缺省的限定符?;愔兴锌衫^承的成員在派生類中都變成私有的。public:基類中所有public成員在派生類中仍為public成員,……,33,構(gòu)造函數(shù)的調(diào)用,,class A {pub

22、lic: A() { ……;}};class B : public A {public: B() { ……;}};,如果現(xiàn)在將類B實(shí)例化成一個對象,構(gòu)造函數(shù)的調(diào)用情況會如何?,34,構(gòu)造函數(shù)的調(diào)用(續(xù)),,類實(shí)例化時,需要調(diào)用其構(gòu)造函數(shù)。如果該類是派生類,必須調(diào)用其父類的構(gòu)造函數(shù),如果其父類也是派生出來的,重復(fù)該過程直至到達(dá)非派生的基類。,35,析構(gòu)函數(shù)的調(diào)用,析構(gòu)函數(shù)的調(diào)用順序與構(gòu)造函數(shù)的調(diào)用順序相反。,,36

23、,構(gòu)造函數(shù)的參數(shù)傳遞,,class A {public: int va; A(int i) { va = i;}};class B:public A {public: int vb; B(int i, int j) { va = i; vb = j}};,37,構(gòu)造函數(shù)的參數(shù)傳遞(續(xù)),class A {public:int va;A(int i) { va = i;}};clas

24、s B :public A {public:int vb;B(int j, int i):A(i) { vb = j;}};,,38,派生類的類型轉(zhuǎn)換,,void main{ First c1; Second c2; First * d1 = new First; Second * d2 = new Second; c1 = c2; d1 = d2;};,如果這樣則不行:

25、c2 = c1;d2 = d1;,39,作用域的分辨,,class A {public: int get () { return 1;}};class B:public {public: int get () { return 2;}};,void main(){ A a; B b; int i = a.get(); int j = b.get();},40,作用域的分

26、辨(續(xù)),,class A {public: int get () { return 1;}};class B:public A {public: int get () { return 2;}};,void main(){ A a; B b; int i = a.get(); int j = b.get(); int k = b.A::get();},作用域分辨操作

27、符,41,性質(zhì)擴(kuò)展,,使用派生類的主要原因是基類提供了派生類需要的部分特征。常?;惡茴愃朴谛枰念悾煌耆嗤?,其中有的函數(shù)需要稍微擴(kuò)展一下。如果在派生類中再次書寫整個函數(shù)會浪費(fèi)很多時間。因此,可以充分利用類的繼承特性,將函數(shù)的功能進(jìn)行擴(kuò)充。,42,性質(zhì)擴(kuò)展(續(xù)一),,假設(shè):有一個類A,它有兩個成員函數(shù),其中一個函數(shù)的功能的清屏,另一個函數(shù)的功能是用“*”畫一條直線,直線的長度根據(jù)參數(shù)決定。現(xiàn)在需要一個新類B,希望它具有清屏的功

28、能,同時具有用“*”畫三角形的功能。,43,性質(zhì)擴(kuò)展(續(xù)二),,*******  n=7的直線****************************  n=7的三角形,44,性質(zhì)約束,,用戶常常找到一些基本合乎要求的類,但是它們可能會有一些不受歡迎的行為。這時,可以使用性質(zhì)約束的方法來使派生類不具有某種功能。,45,性質(zhì)約束(續(xù)),假設(shè):有一個類A,同上例。有一個類B,具有用“*”畫三角形的功能,但是它每次畫三角形之

29、前都會先清屏?,F(xiàn)在需要一個新的類C,希望它具有類B畫三角形的功能,但是在畫三角形之前不會自動清屏。同時它依然保留單獨(dú)清屏的功能。,,46,多重繼承,,C++語言中,一個類的父類并不只局限于一個,實(shí)際上可以有多個,派生類可以從每個父類中繼承性質(zhì)。當(dāng)然,這種繼承性增加了語言和編譯器的復(fù)雜性,但相比之下益處更多?! 《嘀乩^承大大增加了類繼承的靈活性。,47,多重繼承的實(shí)現(xiàn),,假設(shè):有一個類A,具有單獨(dú)清屏的功能。有一個類B,具有用“*

30、”畫直線的功能,但是沒有清屏的功能?,F(xiàn)在需要一個新的類C,希望它具有用“*”畫三角形的功能,又具有單獨(dú)清屏的功能。,48,多重繼承的構(gòu)造函數(shù),,class A {……};class B {……};class C:public A, public B {public: C(int i, int j, int k)},C::C(int i,int j,int k):B(j),A(i) {……};,構(gòu)造函數(shù)的調(diào)

31、用次序是怎樣的?,49,虛基類,,class A {public: int value;};class B :public A{……};class C:public A {……},class D:public B,public C {public: int get() { return value};};,這個value值從何而來?,50,虛基類(續(xù)一),,class A {public:

32、int value;};class B:public virtual A{……};class C:public virtual A {……},class D:public B,public C {public: int get() { return value};};,51,虛基類(續(xù)二),A,A,A,B,C,B,C,D,D,,,,,,,,,,,,,,,,52,1.4 重載,,在OOP中,簡潔性是很重要的。用戶

33、使用系統(tǒng)時對系統(tǒng)了解得越少越好,調(diào)用函數(shù)時需要的細(xì)節(jié)越少越好(參數(shù)的個數(shù)和類型)。如果函數(shù)能夠接受各種類型的參數(shù),由編譯器區(qū)分細(xì)節(jié),則會很方便?! ∵@個目的在C++中可以達(dá)到。但是重載并不是一個全新的概念。,53,重載(續(xù)),,1、函數(shù)重載,2、操作符重載,非成員函數(shù)重載,成員函數(shù)重載,,,,,所謂重載就是同一個符號在不同的上下文中代表不同的含義。,54,重載非成員函數(shù),,void Display(char * string) {……

34、}void Display(long value) {……}void Display(double value) {……}void main(){ Display(“\nPrint this,please!”); Display(123456789); Display(3.14159);},55,重載非成員函數(shù)(續(xù)一),,void Display(char * string) {……}void Dis

35、play(long value) {……}void Display(double value) {……}void main(){ Display(333);},56,重載非成員函數(shù)(續(xù)二),,void Display(char * string) {……}void Display(long value) {……}void Display(double value) {……}void Display(float va

36、lue) {……}void main(){ Display(3.14159);},57,重載非成員函數(shù)(續(xù)三),,void Display(float value) {……}int Display(float value) {……}void main(){ Display(3.14159);},不同的返回值不能用來區(qū)分重載函數(shù)。,58,重載成員函數(shù),,class Example { int valu

37、e;public: void Value(int v) { value =v; } int Value() { return value; }};,void main(){ Example e; e.Value(3); int i = e.Value(); },59,類等級中的重載函數(shù),,class A {public: int f

38、oo (int i) { return i+1;}};class B:public A {public: int foo (float f) { return f+10;}};,void main(){ B b; int i = b.foo(2);},到底應(yīng)該調(diào)用A的foo還是B的foo?,60,類等級中的重載函數(shù)(續(xù)一),,class A {public: int foo (int i)

39、{ return i+1;}};class B:public A {public: int foo (float f) { return f+10;}};,void main(){ B b; int i = b.foo(2);},這種情況不構(gòu)成重載,61,類等級中的重載函數(shù)(續(xù)二),,int f(A & a){ return a.foo(3.14159F);}void main(

40、){ B b; int i = f(b);},i的結(jié)果是多少?,62,作用域分辨符,,class A {public: int foo(int i) {}};class B:public A {public: int foo(float f) {} int foo(int i) {return A::foo(i);}};,void main(){ B b; int

41、i = b.foo(2); int j = b.A::foo(2); int k = b.foo(3.14);},63,參數(shù)匹配,,參數(shù)匹配問題既重要有復(fù)雜。編譯器遇到對重載函數(shù)的調(diào)用時,必須確定調(diào)用哪個函數(shù)。如果能找到參數(shù)完全匹配的函數(shù),自然沒問題,找不到時,則找一替代函數(shù)。此時,編譯器將實(shí)在參數(shù)與所有重載函數(shù)的參數(shù)比較,這個過程叫作參數(shù)匹配。,64,參數(shù)匹配(續(xù)),,1、類型轉(zhuǎn)換不是非要不可的。,2、有時需要作參數(shù)

42、升級。參數(shù)可以沿路徑char→int → long → float → double → long → double升級。,3、參數(shù)轉(zhuǎn)換是可以的。參數(shù)可以根據(jù)標(biāo)準(zhǔn)或用戶定義的轉(zhuǎn)換規(guī)則進(jìn)行轉(zhuǎn)換。,65,重載操作符,,class Example { int value;public: void Value(int v) { value =v; } int Value()

43、 { return value; }};,void main(){ Example e(?); …… e.Value(100+ e.Value());},如果能這樣:e = e+100;既直觀又方便。,66,如何重新理解操作符,,一元操作符 @ X X.@();二元操作符 X @ Y X.@(Y);,@是一個操作符,但是也可以被理解為一個成員函數(shù)。,67,重載操作符實(shí)

44、例,,class Counter { int value;public: Counter(int i) { value =i; } Counter operator !() {return Counter(!value); } Counter operator +(Counter &c) { return Counter(value+c.value); }};

45、,void main(){ Counter c1(3),c2(5); c1 = !c1; c1 = c1+c2; },68,重載操作符實(shí)例(續(xù)),,class Counter { int value;public: Counter(int i) { value =i; } Counter operator !( int i) {return Counter(!val

46、ue); } Counter operator +(Counter &c) { return Counter(value+c.value); }};,放一個不用的參數(shù)可以嗎?,返回類型為什么經(jīng)常是對象類型。,c1+c2+c3+c4+c5,69,名字分裂及其規(guī)則,,名字分裂的目的:使產(chǎn)生重載的符號在編譯系統(tǒng)內(nèi)部有唯一的名字,從而使得它們在目標(biāo)代碼中有不同的入口地址。名字分裂原則:@函數(shù)名$q符號化的參

47、數(shù)表void Counter::Value(int k)@Counter@Value$qi,70,1.5 多態(tài)性,,多態(tài)性是指C++的代碼可以根據(jù)運(yùn)行情況的不同執(zhí)行不同操作。這通常不能由程序員來直接控制,而必須依靠面向?qū)ο蟮某绦蛟O(shè)計的特性,使對象對自身的運(yùn)行進(jìn)行跟蹤。  多態(tài)性是通過類的體系結(jié)構(gòu)來實(shí)現(xiàn)的,不過,只有類成員函數(shù)可以具有多態(tài)性,而不是整個類都具有多它性。,71,先期聯(lián)編,,class A {public: v

48、oid foo ();};class B:public A {public: void foo ();};,int f(A & a){ return a.foo();}void main(){ B b; f(b);},這個地方最終調(diào)用的是哪個類的foo函數(shù)?為什么?,72,遲后聯(lián)編,,如果在上例中需要f函數(shù)根據(jù)形式參數(shù)中傳遞進(jìn)來的對象的類型自動調(diào)用該類的foo函數(shù),則需要激活C+

49、+的遲后聯(lián)編的功能,使程序在執(zhí)行的過程中自動選擇相應(yīng)的函數(shù)。,73,遲后聯(lián)編(續(xù)),,class A {public: virtual void foo ();};class B:public A {public: virtual void foo ();};,int f(A & a){ return a.foo();}void main(){ B b; f(b);},

50、這時將根據(jù)實(shí)際的參數(shù)類型來選擇相應(yīng)的函數(shù)。,74,虛函數(shù),,聲明為virtual的函數(shù)為虛函數(shù)。通過聲明函數(shù)為virtual,來人為指定遲后聯(lián)編。遲后聯(lián)編只能用于類等級中的對象。對于不被任何類繼承的類,聲明其函數(shù)為虛函數(shù),從語法上來講是正確的,但是會引起不必要的運(yùn)行時刻開銷。,75,函數(shù)覆蓋,,1、虛函數(shù)的參數(shù)個數(shù)與類型。,2、虛函數(shù)的傳遞。,使用虛函數(shù)后,派生類中的函數(shù)可以覆蓋原有基類中函數(shù)的功能,這被稱為函數(shù)覆蓋。構(gòu)成函數(shù)覆蓋的條件

51、是:,76,抽象類,,由虛函數(shù)的傳遞性可以看出,出現(xiàn)在類等級頂部及其附近的類常常有多個空的虛函數(shù)。如果一個類只有空虛函數(shù),實(shí)例化這樣的類有意義嗎?但是,這種實(shí)例化是允許的,其結(jié)果是得到一個占有內(nèi)存卻不做任何操作的無用的對象。為了避免這種情況的發(fā)生,C++中引進(jìn)了可以被繼承但是不能實(shí)例化的抽象類。,77,純虛函數(shù),,至少包含一個純虛函數(shù)的類被稱為抽象類。,class A {public: virtual void foo ()

52、= 0;};,注意純虛函數(shù)的定義方法。,78,純虛函數(shù)的使用,class A {public: virtual void foo ()=0;};void main(){ A a; a.foo();},,注意:抽象類不能實(shí)例化。,79,純虛函數(shù)的使用,class A {public: virtual void foo ()=0;};class B:public A {public:

53、 virtual void foo ();};,void main(){ B b; b.foo();},,注意:純虛函數(shù)一定要被覆蓋。,80,作用域分辨符,,class A {public: virtual void foo ();};class B:public A {public: virtual void foo ();};,int f(A & a){ retur

溫馨提示

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

評論

0/150

提交評論