《你必須知道的.NET》讀書筆記一:小OO有大智慧
此篇已收錄至《你必須知道的.Net》讀書筆記目錄貼,點擊訪問該目錄可以獲取更多內容。
一、對象
(1)出生:系統首先會在內存中分配一定的存儲空間,然後初始化其附加成員,調用構造函數執行初始化,這樣一個對象實體就完成了出生過程。
Person aPerson = new Person("小周" , 25);
(2)旅程:在某種程度上就是外界通過方法與對象交互,從而達到改變對象狀態信息的過程。這也和人的生存之道暗合。
aPerson.ChangeName("Edison Chou");
(3)插曲:
3.1 繼承之訪問修飾符
-
- public:最高訪問權限,公司的董事會具有最高的決策權與管理權;
- protected:部門經理,具有對本部門的直接管轄權,面向對象中體現為子類繼承縱向關系的訪問約定;
- internal:類似於公司的職能部門的職責,不管是否具有上下級關系,人力資源部都有管轄其他部門員工的能力;(面向對象中體現為同一程序集的訪問權限,只要是隸屬於同一程序集,對象即可訪問其屬性等,不管是否存在隸屬關系;)
- protected internal:副總經理,從橫向到縱向都有管理權;
- private:最低訪問權,公司一般職員,管好自己即可;
3.2 多態實現方式-->在不同的情況下實現了不同的操作,而把決定權交給系統自行處理
-
- 接口實現多態
- 抽象類實現多態
(4)消亡:對象和人,有生必然也有死。
在.NET的世界中,對象的生命周期由GC來控制:GC管理所有的托管堆對象,當內存回收執行時,GC檢查托管堆中不再被使用的對象,並執行內存回收操作;不被應用程序使用的對象,指的是對象沒有任何引用。
二、繼承
(1)繼承的分類:實現繼承與接口繼承
(2)繼承的本質:面向對象中類與類之間的一種關系;繼承的類稱為子類、派生類;而被繼承類稱為父類、基類或超類;通過繼承,使得子類具有父類的屬性和方法,同時子類也可以通過加入新的屬性和方法或修改父類的屬性和方法建立新的類層次;
(3)實現繼承與接口繼承的區別:
-
- 抽象類適合於有族層概念的類間關系
- 接口著重於CAN-DO關系類型,而抽象類則偏重於IS-A式的關系
- 接口多定義對象的行為;抽象類多定義對象的屬性
- 版本式的問題最好以抽象類來實現
- 因為值類型是密封的,所以只能實現接口,而不能繼承類
- 抽象類適合於有族層概念的類間關系
(4)面向對象基本原則:多聚合,少繼承;低耦合,高內聚;
Adapter模式實例-->類的Adapter模式與對象的Adapter模式相比,對象的Adapter模式通過聚合而非繼承的方式來實現對原有系統的擴展,松散耦合,較少的新類型。
#region 類的Adapter模式 interface ITweetable { void ToTweet(); } public class ChickenAdapter : Chicken, ITweetable { public void ToTweet() { Console.WriteLine("Chicken crows."); } } #endregion #region 對象的Adapter模式 public class BirdAdapter : ITweetable { private Bird _bird; public BirdAdapter(Bird bird) { _bird = bird; } public void ShowType() { _bird.ShowType(); } public void ToTweet() { //為不同的子類實現不同的ToTweet行為 } } #endregion
三、封裝
(1)封裝的作用:
-
- 隱藏系統實現的細節,保證系統的安全性和可靠性;
- 提供穩定不變的對外接口,因此系統中相對穩定部分常被抽象為接口;
- 封裝保證了代碼模塊化,提高了軟件的復用和功能分離;
(2)結論:封裝就是一個包裝,將包裝的內外分為兩個空間,對內實現數據私有,對外實現方法調用,保證數據的完整性和安全性。
/// <summary> /// 用戶類 /// </summary> public class Client { private string name; //用戶姓名 public string Name { get { return name; } set { name = value == null ? String.Empty : value; } } //private string firstName; //private string secondName; //public string MyName //{ // get { return firstName + secondName; } //} private int age; //用戶年齡 public int Age { get { return age; } set { if ((value > 0) && (value < 150)) { age = value; } else { throw new ArgumentOutOfRangeException("年齡信息不正確。"); } } } private string password; //用戶密碼 public string Password { get { return password; } set { if (value.Length < 6) password = value; } } //public string get_Password() //{ // return password; //} //public string set_Password(string value) //{ // if (value.Length < 6) // password = value; //} }
四、多態
(1)定義:可以呈現不同形式的能力或狀態;
(2)分類:基類繼承式多態與接口實現式多態;
(3)運行機制:動態綁定(在運行期通過檢查虛擬方法表來確定動態關聯覆寫的方法)
(4)DEMO:多態版萬能文件加載器(FileLoader)
interface IFileOpen { void Open(); } enum FileType { doc, pdf, txt, ppt, jpg, gif, mp3, avi } abstract class Files : IFileOpen { private FileType fileType = FileType.doc; public FileType FileType { get { return fileType; } } public abstract void Open(); } abstract class DocFile : Files { public int GetPageCount() { //To do code return 0; } } abstract class ImageFile : Files { public void ZoomIn() { //放大比例 } public void ZoomOut() { //縮小比例 } } abstract class MediaFile : Files { public void Play() { //播放媒體 } public void Pause() { //暫停播放 } public void Stop() { //停止播放 } } class WordFile : DocFile { public override void Open() { Console.WriteLine("Open the Word file."); } } class PdfFile : DocFile { public override void Open() { Console.WriteLine("Open the Pdf file."); } } class JpgFile : ImageFile { public override void Open() { Console.WriteLine("Open the Jpg file."); } } class AviFile : MediaFile { public override void Open() { Console.WriteLine("Open the Avi file."); } } class MpegFile : MediaFile { public override void Open() { Console.WriteLine("Open the Mpeg file."); } } class LoadManager { private IList<Files> files = new List<Files>(); public IList<Files> Files { get { return files; } } public void LoadFiles(Files file) { files.Add(file); } /// <summary> /// 打開所有文件 /// </summary> public void OpenAllFiles() { foreach(IFileOpen file in files) { file.Open(); } } /// <summary> /// 打開單個文件 /// </summary> /// <param name="file">文件接口對象</param> public void OpenFile(IFileOpen file) { file.Open(); } /// <summary> /// 獲取文件類型 /// </summary> /// <param name="fileName">文件名</param> /// <returns>文件類型</returns> public FileType GetFileType(string fileName) { FileInfo fi = new FileInfo(fileName); return (FileType)Enum.Parse(typeof(FileType), fi.Extension); } } class FileClient { static void Main(string[] args) { //首先啟動文件加載器 LoadManager lm = new LoadManager(); //陸續添加要處理的文件 lm.LoadFiles(new WordFile()); lm.LoadFiles(new PdfFile()); lm.LoadFiles(new JpgFile()); //打開文件 foreach (Files file in lm.Files) { //if(file is 爺爺選擇的) //{ // file.Open(); //} file.Open(); } Console.ReadKey(); } }
五、接口
(1)本質:一種“契約”,用於規定一種規則由大家遵守;通過IL分析(借助於Reflector工具)可知,接口本質上仍然被標記為.class,一個不能被實例化的類。實現了接口的類方法在IL標記為override,表示覆寫了接口方法實現。
public interface IDriveable { void Drive(); } public class BusDriver : IDriveable { public void Drive() { Console.WriteLine("有經驗的司機可以駕駛公共汽車。"); } } public class CarDriver : IDriveable { public void Drive() { Console.WriteLine("小車司機開小汽車。"); } } public class TractorDriver : IDriveable { public void Drive() { Console.WriteLine("拖拉機司機駕駛拖拉機。"); } } public class AircraftDriver : IDriveable { public void Drive() { Console.WriteLine("飛行員可以駕駛飛機。"); } } public class DriverSchool { public static void Main_1_5_1()//Main_1_5_1 { IList<IDriveable> drivers = new List<IDriveable>(); drivers.Add(new BusDriver()); drivers.Add(new CarDriver()); drivers.Add(new TractorDriver()); foreach (IDriveable driver in drivers) { driver.Drive(); } } }
(2)規則:
-
- 接口隔離原則強調接口應該被實現為具有單一功能的小接口
- 接口支持多繼承,既可以作用於值類型也可以作用於引用類型
- 接口不能被實例化,沒有構造函數,接口成員被隱式聲明為public
- 禁止為已發布的接口添加新的成員
本章思維導圖
作者:周旭龍
出處:http://www.cnblogs.com/edisonchou/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
《你必須知道的.NET》讀書筆記一:小OO有大智慧