abstract:1.抽象什么是面向對象的抽象?這里不說純理論的知識,其實說白了,就是從我們自身觀察者角度找出類和對象,構建對象模型。在實際操作中,我們只需要記住下面幾個特質即可:1. 模塊間的關聯(lián)強度應該是最低的;(低耦合) [重要]2. 模塊內各個元素的關聯(lián)強度是緊密的;(高內聚) [重要]3. 抽象足夠多的特征來進行有意義和有效的交互; [了解]4. 類和模塊的接口記錄全部特征; [了解]5. 訪問抽象底層表
1.抽象
什么是面向對象的抽象?這里不說純理論的知識,其實說白了,就是從我們自身觀察者角度找出類和對象,構建對象模型。
在實際操作中,我們只需要記住下面幾個特質即可:
1. 模塊間的關聯(lián)強度應該是最低的;(低耦合) [重要]
2. 模塊內各個元素的關聯(lián)強度是緊密的;(高內聚) [重要]
3. 抽象足夠多的特征來進行有意義和有效的交互; [了解]
4. 類和模塊的接口記錄全部特征; [了解]
5. 訪問抽象底層表現(xiàn)形式才能夠有效地實現(xiàn)操作。 [了解]
2.封裝
我們熟知,C#的class對象中,主要分為field(字段)、property(屬性)和method(方法)。
如:
public class Person { #region Fields private string _name; private bool? _sex; #endregion #region Constructors public Person(string name) : this(name, null) { } public Person(string name, bool? sex) { this._name = name; this._sex = sex; } #endregion #region Properties public string Name { get { return this._name; } } public bool? Sex { get { return this._sex; } } #endregion #region Methods private string GetSexName(bool? value) { string sexName = null; switch (value) { case null: sexName = "undefined"; break; case true: sexName = "male"; break; case false: sexName = "female"; break; default: break; } return sexName; } public void Speak(string words) { Console.WriteLine(string.Format("{0}({1}) says: {2}", this._name, this.GetSexName(this._sex), words)); } #endregion }
我們需要注意的封裝對象的修飾符,分別用修飾符public, internal, protected, private設定,可作用于類的字段,屬性和方法,甚至于類對象本身。具體的訪問權限如下:
public: 所有對象都可以訪問;
protected internal:同一個程序集內的對象,或者該類對象以及子類可訪問;
internal:同一個程序集的對象可訪問;
protected:該類對象以及其子類對象可訪問;
private: 只有該類對象本身在對象內部可訪問;
對Person類內部代碼的解析(針對于需掌握基礎知識的讀者)
#region Your Description Here
#endregion
折疊代碼用,若代碼很長,我們可以用此方式折疊代碼。折疊后,在VS編輯器可以折疊,折疊后只會看到對該折疊部分的描述文字,即:Your Description Here
1. field定義
_name和_sex是兩個字段,并定義為private,即:只能在該類對象內部可訪問;
其中:bool? 這個是對bool類型的一個擴展。我們所熟知的bool是一個值類型,在其后加上"?",即是一個新的數(shù)據(jù)類型,在bool的基礎上擴展為可為null值的數(shù)據(jù)類型(引用類型)。
我們可以從下面的GetSexName函數(shù)略知其常見用法:
private string GetSexName(bool? value) { string sexName = null; if (value == null) { sexName = "undefined"; } else { sexName = value.Value ? "male" : "female"; } return sexName; }
2. constructor定義
定義了兩個構造函數(shù)(constructor)
public Person(string name) : this(name, null) { } public Person(string name, bool? sex) { this._name = name; this._sex = sex; }
我們可以在實例化的時候,有兩種選擇。一種是傳一個參數(shù)name,另一種是傳兩個參數(shù)name和sex。
若只傳一個參數(shù),則會選擇第一個構造函數(shù):
public Person(string name) : this(name, null) { }
其中,該構造函數(shù)會再次調用兩個參數(shù)的構造函數(shù),即內部構造函數(shù)間可用上述代碼的方式調用。若該構造函數(shù)內部有自身的邏輯,那么,這些邏輯會在調用完:this(...)函數(shù)后再執(zhí)行。
3. Property定義
public string Name { get { return this._name; } } public bool? Sex { get { return this._sex; } }
只定義了get,并為定義set
如若想要外部可對property進行賦值,可加上set,例Sex屬性:
public bool? Sex { get { return this._sex; } set { this._sex = value; } }
4. Method定義
定義了兩個函數(shù),一個是public void Speak(string words),另一個是private string GetSexName(bool? value)
這里,我們要新增一個知識點,即一個針對函數(shù)傳參的語法糖,例Speak函數(shù):
public void Speak(string words="Hello, world!") { Console.WriteLine(string.Format("{0}({1}) says: {2}", this._name, this.GetSexName( this._sex), words)); }
細細對照,可發(fā)現(xiàn)在Speak函數(shù)傳參words的地方,有一個預定義為"Hello, world!"的值。
上面的代碼即類似于下面的函數(shù)重載效果:
public void Speak() { this.Speak("Hello, world!"); } public void Speak(string words) { Console.WriteLine(string.Format("{0}({1}) says: {2}", this._name, this.GetSexName(this._sex), words)); }
兩種寫法,我們在調用的時候,都可以傳words參數(shù)的值,也可以不寫,效果是一樣的。但前面的那種寫法更加簡潔明了,現(xiàn)多被廣泛使用。