面向對象思想有三個核心要素:封裝、繼承與多態。如能正確理解這三要素,那麼基本上可以算是在編程中建立了面向對象思想。在第二節中我曾介紹,在C#中,所有數據類型的實例都是“對象”,不過最能體現對象特質的類型,還是“類”,同時它也是C#中最重要、最頻繁使用的類型。接下來,我將通過介紹C#的類,來充分理解對象封裝的概念。
所謂“對象”,形象地說,我們可以把它理解為一塊積木。設計積木的人需要設計積木的外觀與形狀,還有內部的材質。堆積木的人對於內部的材質並不關心,他們只需要根據不同的外觀與形狀來決定堆放的位置。因此,對於開發者而言,要設計面向對象的程序,同時會是兩個迥然不同的身份:設計者與使用者。
先談談使用者。使用者的身份,就是利用已經提供給你的所有對象,根據需求,設計出自己需要實現的程序。就如堆積木的過程。這恰恰是面向對象編程的優勢所在,那就是“對象的重用”。已經設計好的對象,可以被不同的使用者調用,這些功能既然已經實現,對於使用者而言,當然就免去了自己去設計的過程。正如堆積木那樣,既然有了現成設計好的積木,使用者所要做的工作就是把這些積木最後組合起來,堆成不同的形狀。.Net Framework所提供的類庫,就是這樣的積木。
例如我們想把一個int類型轉換成字符型,就沒有必要自己去實現這種轉換,直接調用.Net Framework提供的功能就可以了:
int i = 10; string s = i.ToString();
再比如我們想彈出一個Windows消息框,同樣可以直接使用.Net Framework現有的類庫:
MessageBox.Show(“Message”);
在上述的例子中,i和MessageBox都是一個對象。
再談談設計者的身份。雖然.Net Framework的類庫功能已經非常強大,但它不可能考慮到業務的方方面面,如果需要使用一個根本就不存在的對象,此時就需要自己來設計了。例如圖書管理系統,可能就需要用戶,圖書等對象。這就需要開發者自己來設計這些對象。
既然最能體現“對象”思想的類型是“類”,我就來介紹一下C#中的類類型。C#中類的關鍵字是class。在一個class對象中,主要分為field(字段)、property(屬性)和method(方法),前面兩個對應的是對象的屬性,而method則對應對象的行為。一個典型的class定義如下所示:
public class User { private string m_name; private string m_password; private int m_tryCounter; public string Name { get {return m_name;} set {m_name = value;} } public string Password { get {return m_password;} set {m_password = value;} } public void SignIn() { if (m_tryCounter < 3) { if (IsValid()) { m_tryCounter = 0; Console.WriteLine("User {0} was signed in.", m_name); } else { m_tryCounter++; Console.WriteLine("User {0} is invalid. Can’t Sign in.", m_name); } } else { Console.WriteLine("You try to sign in more than 3 times. You are be denied."); } } public void SignOut() { m_tryCounter = 0; Console.WriteLine("User {0} was signed out.", m_name); } private bool IsValid() { if (m_name.ToUpper() == "ADMIN" && m_password == "admin") { return true; } else { return false; } } }
字符串m_name,m_password,m_tryCounter就是類User的字段,Name,Password是類User的屬性,而SignIn、SignOut和IsValid則是類User的方法。
關於field,property和method,我會在之後的文章中介紹,這裡主要介紹的是在這個類中出現的修飾符public、private等相關的知識。
前面說到對象好比是一個積木,設計者需要定義好這個積木的外觀和形狀,也要考慮積木內部的制作,例如選用的材質,以及是空心還是實心。如果將這個積木剖開來看,實際上該對象應分為內、外兩層。由於使用者只關心外部的實現,因此設計者就需要考慮,哪些實現應暴露在外,哪些實現應隱藏於內。這就體現了對象的封裝的思想。