最近在研究.NET Core的一些類庫源碼的時候發如今底層類庫中使用了大量的抽象類,然而發現本身搬磚這麼多年好像歷來沒有在項目中使用抽象類或者抽象方法去實現某個功能模塊,而且對修飾符Abstract概念也只懂得一些皮毛(也就是面試的時候會問下其基本做用)。固然,我們不懂就要去慢慢的學習瞭解,不能讓這些不懂的技術和知識點一直困擾着咱們。接下來就讓咱們一塊兒去探索C# Abstract修飾符的做用,而且瞭解在什麼場景下咱們會使用到抽象類,從而提高咱們項目的健壯性。html
基本概念:abstract修飾符指示要修改的東西有缺失或不完整的實現。面試
修飾範圍:abstract修飾符能夠用於修飾類、方法、屬性、索引器(indexer)和事件。ide
public abstract class HttpRequest{}
//todo:抽象方法不能提供實際的實現,所以沒有方法主體(而且抽象方法只可以在抽象類中聲明) public abstract void ActionMethod();
public abstract string ContentType { get; set; }
public string this[int index] => $"獲取_{index}";
//首先聲明該事件的委託類型 public delegate void BoilerLogHandler(string status); // 基於上面的委託定義事件 public abstract event BoilerLogHandler BoilerEventLog;
是一個可以提供給多個派生類共享的通用基類。函數
接口提供了派生類應遵循的標準結構。學習
一、抽象類是特殊的類,除了不能實例化(只能經過實例化繼承抽象方法的派生類來獲取抽象類中的成員)外,具備類的其餘特性(能夠單繼承)。
二、抽象類能夠定義抽象方法,抽象方法沒有現實。
三、繼承抽象類的類必須把裏面的抽象成員(成員包括:方法,屬性,索引器,事件)所有重寫(orveride),抽象類除外。優化
一、接口沒法直接進行實例化。ui
二、一個類或結構能夠實現多個接口。this
三、實現接口的任何類或結構都必須實現其全部成員。spa
四、接口包含的成員只有方法,屬性,索引器(有參屬性),事件四種成員。.net
五、接口不能包含實例字段、實例構造函數或終結器。
六、默認狀況下,接口成員是公共的,不能有其餘的修飾符。
一、均可以被繼承
二、都不能直接被實例化
三、均可以包含方法聲明且都沒有實現
四、派生類必須實現未實現的成員
一、接口能夠被多重實現,抽象類只能被單一繼承。
二、接口能夠用於支持回調,繼承並不具有這個特色。
三、抽象類能夠定義字段、方法、屬性、事件、索引器的實現。接口只能定義屬性、索引器、事件、和方法聲明,不能包含字段。
四、接口中的成員訪問類型默認爲公共的,不能有其餘的訪問修飾符修飾。
五、定義的關鍵字不同,抽象類須要使用abstract,而接口則使用interface。
一、抽象類表共性(常應用在具備相同的行爲和特徵中),而接口則表規範(用於定義一種行爲)。
二、抽象類主要用於關係密切的對象,而接口最適合爲不相關的類提供通用功能。
三、若是要設計大的功能單元,則使用抽象類;若是要設計小而簡練的功能塊,則使用接口。
四、若是預計要建立組件的多個版本,則建立抽象類。接口一旦建立就不能更改。若是須要接口的新版本,必須建立一個全新的接口。
五、若是建立的功能將在大範圍的全異對象間使用,則使用接口;若是要在組件的全部實現間提供通用的已實現功能,則使用抽象類。
六、分析對象,提煉內部共性造成抽象類,用以表示對象本質,即「是什麼」。爲外部提供調用或功能須要擴充時優先使用接口。
七、好的接口定義應該是具備專注功能性的,而不是多功能的,不然形成接口污染。若是一個類只是實現了這個接口的中一個功能,而不得不去實現接口中的其餘方法,就叫接口污染。
實例一:就像鐵門木門都是門(抽象類),你想要個門我給不了(不能實例化),但我能夠給你個具體的鐵門或木門(多態);並且只能是門,你不能說它是窗(單繼承);一個門能夠有鎖(接口)也能夠有門鈴(多實現)。 門(抽象類)定義了你是什麼,接口(鎖)規定了你能作什麼(一個接口最好只能作一件事,你不能要求鎖也能發出聲音吧(接口污染))。
實例二:好比說咱們一個班級有不少爲同窗,這些同窗都有着各自的特長,愛好,穿衣打扮的風格,所以咱們減小代碼冗餘能夠定義一個通用的學生抽象類用來描述學生的身高,體重,姓名,愛好,特徵等相關特徵和行爲的公共抽象類。
實例三:咱們須要建立 「狗」、「貓」、「魚」、「馬」這些對象(類),咱們能夠說他們有一些共同的屬性像嘴巴、尾巴、重量、顏色、大小等等一些共同的屬性(properties),可是它們彼此的屬性的形狀是不一樣的(如嘴巴),在這種狀況下,咱們若是一個個去定義各自相似的屬性是否是比較繁瑣?若是用抽象類是否是很方便的給他們去繼承。抽象類也有個更加好的地方,體如今「同質異像」就是實質相同實現形式不一樣的方法繼承上,例如上面的狗、貓、馬等的呼吸這個方法或者跑的速度的方法形式不一樣,咱們這個是用定義一個抽象方法,讓他們各自的類去實現它是否是很方便。「抽象」的意義正在於此。將共同的東西抽出來封裝,但不實現只給繼承。
經過對抽象類的深刻理解發現原來在程序設計方面須要考慮優化的問題仍是有不少不少的,抽象類和接口的選擇就是一個很典型的例子。每每咱們會圖簡單而去直接定義接口使用,卻每每忽視了後期的軟件的健壯性和可拓展性。在之後的開發中須要多思考這方面的問題。最後假如文章有什麼須要補充或者不足的地方但願你們指正,謝謝。
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/abstract-and-sealed-classes-and-class-members
https://blog.csdn.net/lizhenxiqnmlgb/article/details/82346478
https://kb.cnblogs.com/page/41836/