一、類和對象
1,面向過程程序設計(自頂向下設計)
分析出解決問題所需的步驟,然后用函數把這些步驟一一實現,使用的時候一個一個調用
過程式設計對于比較復雜的問題,或是在開發中需求變化比較多的時候,往往顯示力不從心
·? 這是因為過程式的設計是自上而下的,這要求設計者在一開始就要對需要解決的問題有一定的了解。在問題比較復雜的社會,要做到做一點會比較困難。
·? 開發一個系統的過程往往也是一個對系統不斷了解和學習的過程,而過程式的設計方法忽略了這一點。
·? 過程式設計使用函數定義操作;使用變量定義事物的屬性、特征;這樣做的結果是數據和操作被分離。
·? 比如go()函數表示汽車前進,而汽車的排量、燃料種類等等都是和go()函數分離的。
·? 數據和操作被分離,容易導致對一種數據的操作分布在整個數據的各個角落,從而造成系統維護困難。系統越大情況越糟糕。
2,面向對象程序設計
·? 面向對象從問題的一部分入手,把構成問題的事物分解成許多對象,建立對象的目的不是為了完成一個步驟,而是為了描述某個事物自身及其在整個解決問題的過程中的行為。
·? C++語言中,對象抽象成類,類成為模塊化元素,是劃分程序的基本單位。
·? 類將對象的數據和操作(成員函數)封裝在一起,可以說這就是對象設計方法最基本的特征。
問題:
現在將一批鴨子用若干個盒子包裝起來。將這一過程用程序表現出來。
面向過程的設計方法:
涉及到三個操作,對應三個函數:
? ①open() 把盒子打開,目標是得到打開的盒子
? ②put()把鴨子裝進去,目標是得到里面裝著鴨子的盒子
? ③close()把盒子蓋好,目標是獲得蓋好盒蓋的有鴨子的盒子
定義問題中的數據:
用數字state[]表示盒子的狀態,state[k]表示第k個盒子的情況。可將盒子狀態分為4種情況(用0-3表示):
0-----未開蓋的空盒
1------開蓋的空盒
2-------裝好鴨子、未蓋好蓋子的盒子
3-------裝好鴨子并蓋好蓋子的盒子
用duckState[] 表示鴨子的狀態,duckState[n]表示第n只鴨子的情況。
鴨子的狀態是未被裝入和已被裝入兩種,因此可以用bool類型數組表示。
int open(int state[],int k)打開第k個盒子,成功返回編號,失敗返回-1
int put(int state[],int k,bool duckState[],n)將第n只鴨子放入第k個盒子,成功則返回盒子編號,失敗返回-1
void close(int state[],int k)將第k個盒子蓋好
至此,三個步驟都用函數實現了,感覺還行,下面我們看看面向對象的方法
面向對象的分析設計方式
面向對象的方法不是從“怎么做”出發,而是從“是什么”出發考慮問題。首先尋找問題中的對象。為了發現對象,要在系統說明的文檔中查找名詞。
在問題中,我們可以找到重要的名詞:盒子,鴨子
然后將這些對象的共有特性以及其責任抽象稱為特殊的數據類型------類
在C++中,類用class定義
考察盒子對象,顯然“狀態”是盒子的屬性,可以把“將鴨子放入盒子中”歸納為盒子的任務。
為了完成把鴨子裝進盒子的任務,需要做三個動作:
打開蓋子,裝入,合上蓋子。每個導致對應類的一個成員函數。
這樣一來,我們要做的是對某個盒子發出指令:
①k號盒子,請把蓋子打開
②k號盒子,請把第n只鴨子放入
③k號盒子,請把蓋子蓋上
每個指令計算調用一個成員函數。
盒子類可定義如下:
class BOX{int ID; //盒子編號,為什么不是數組?int state; //盒子狀態,為什么不是數組?int open(); //打開盒子,為什么沒有參數?int put(bool duckState[],n); //將第n只放入盒子void close(); //將蓋子蓋好,為什么沒有參數?
}
放入物品的過程中盒子b[k]應當執行如下代碼:
b[k].open()
b[k].put(duckState,n);
b[k].close()
·? 在面向過程的方法中,數據和函數是分離的,數據可能散落在程序的各個角落,不易維護;
?? 而面向對象的方法中,函數和數據結合在一起,每個對象都有自己獨立的數據,含義清晰,易于維護。
·? 在面向過程方法過程中,需要在開始階段就分析清楚每個過程的作用,并編寫合適的函數,一旦在后續工作中發現初始的分析不恰當,則可能改動很大;而面向對象的設計方法允許開發者從問題的局部開始,先找出類,在找出類之間的關系,在開發過程中逐步加深對系統的理解
如何聲明一個類
class 類名? // class是聲明類的關鍵字
{
private:
//私有成員數據(屬性)和私有成員函數(方法)
protected:
//保護成員數據(屬性)和保護成員函數(方法)
public:
//公有成員數據(屬性)和公有成員函數(方法)
};
//花括號內部分是類體。類聲明以分號結尾。
聲明一個銀行賬戶類
class Account
{
public: // 公有成員int ID // 賬戶IDchar Name[20]; //姓名float balance; //余額int withdraw(float m) //取出數量為m的錢{if(balance > m){balance = balance - m; return 1;}else return -1;}void deposits(float m);
};
void Account::deposits(float m){ //在類內部或外部實現函數都可balance = balance + m;
}
聲明具體對象或對象數組
正如“人”是抽象的定義,生活的舞臺都是具體等等張三,李四在表演;
“賬戶”類也是抽象的,只有定義了具體賬戶,才能執行某些操作。
定義一個賬戶對象:
Account my Account;
而下面語句則定義了包含10個對象的數組:
Account account[10]
不論是定義一個對象,還是一組對象,C++都會在內存中為每一個對象分配必要的空間
公有函數的使用方法
格式:
對象名.函數名(實際參數)
比如,要向myAccount存入600元,格式如下:
myAccount.deposit(600.0)
注意:僅僅對公有函數可以這樣使用
類對象的公有變量也直接修改或顯示。比如:
myAccount.ID = 10001; //設定賬戶ID
同類對象之間可以賦值比如下面的語句:
myAccount = account[0];
·? 類也可以作為一個函數的參數或返回值出現,下面定義一個不屬于任何類的函數:
//從賬戶A轉m元到賬戶B
bool transfer(Account A , Account B, float m){if(A.withdraw(m) == 1){ //若A取款成功B.deposits(m); //向B存款return true;}else return false;
}
注意:調用函數:
transfer(myAccount,account[0],1000.0);
不會修改myAccount和account[0]對象的數值!
原理:
·? 雖然函數中A和B出現在參數中,不是在transfer函數體內定義,但A和B仍是此函數內部的局部變量
·? 對象myAccount和account[0]分別賦值給A和B(值傳遞)。這里myAccount和account[0]都是彼此獨立的對象
·? 在函數中從賬戶A轉m元到賬戶B。但是myAccount和account[0]對象無任何變化
·? 函數transfer執行完畢后,其中的局部變量A和B也隨之消失。
解決本問題需要利用指針或引用
?
?
?