一、多態簡介
????????在面向對象編程的過程中,多態體現出來的是【一個接口,多個功能】;多態性體現在2個方面:
????????1、程序運行時,在方法參數、集合或數組等位置,派生類對象可以作為基類的對象處理;這樣該對象聲明的類型就與運行時的類型不同了;
????????2、基類可以定義并實現虛方法,派生類可以重寫這些虛方法;在程序運行時,可以調用基類方法執行派生類的重寫方法。
????????在C#中要實現多態,必須使用abstract、virtual這個兩個修飾符來定義,使用override來重寫方法。 多態又可以分為:【靜態多態性】、【動態多態性】;
二、靜態多態性
?????????靜態多態性(即:使用static修飾;變量、函數的響應是在程序編譯時就發生了)若一個方法被static聲明,則該方法就是靜態方法,那么編譯器就會在編譯時保留這個靜態方法的實現;也就是說這個靜態方法只屬于類,而不屬于任何實例,無論實例是否存在,都可以可直接調用這個靜態方法。
? ? ? ? C#中的靜態多態性分為兩種:【函數重載】、【運算符重載】
//靜態函數重載示例public class StaticReload{public static void Greet(){Console.WriteLine($"你好,歡迎訪問");}public static void Greet(string greetMsg){Console.WriteLine(greetMsg);}}//Class_endclass Program{static async Task Main(string[] args){StaticReload.Greet();StaticReload.Greet("Quartz定時任務測試");}}
?
運算符重載 - 定義一元運算符、算術運算符、相等運算符和比較運算符。 - C# reference | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/operator-overloading
三、動態多態性
????????動態多態性(無static修飾;變量、函數的響應是在程序運行起來后發生的)。
?3.1、abstract(抽象)
abstract 關鍵字 - C# reference | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/abstract????????【abstract】關鍵字可用于修飾類(Class)、方法(Method)、屬性(attribute)、索引(index)和事件(Event);
? 3.1.1、抽象類
?????????在類(class)前面放置修飾符【abstract】
,則可以將類聲明為抽象類;
序號 | 抽象類特點 |
1 | 抽象類不能實例化 |
2 | 抽象類可能包含抽象方法和訪問器 |
3 | 無法使用?sealed?修飾符來修改抽象類 因為兩個修飾符的含義相反【? |
4 | 派生自抽象類的非抽象類,必須實際實現所繼承抽象類的全部抽象內容(抽象方法、屬性、索引、事件) |
public abstract class MyShape{public abstract float GetArea();public abstract string Name { get;}public abstract Action<float> GetAction();}//Class_endpublic class Circle : MyShape{private int _radius;public Circle(int r){_radius = r;}public override string Name {get => "我是圓";}public override Action<float> GetAction(){throw new NotImplementedException();}public override float GetArea(){var tmp =Math.PI * (_radius * _radius);float result =(float)tmp;return result;}}//Class_endclass Program{static async Task Main(string[] args){MyShape myShape = new Circle(3);float shapeArea = myShape.GetArea();Console.WriteLine($"Name:{myShape.Name} ShapeArea: {shapeArea}");}}
?
抽象類、密封類及類成員 - C# | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/abstract-and-sealed-classes-and-class-members?
? 3.1.2、抽象方法
???在方法、屬性、索引、事件前面放置修飾符【
,則可以聲明為抽象方法、屬性、索引、事件;且表明方法、屬性、索引、事件不包含實現。abstract
】
序號 | 抽象方法特點 |
1 | 只有抽象類中才允許聲明抽象方法 |
2 | 抽象方法不提供實際實現,所以聲明僅以分號結尾,沒有大括號{};具體實現由一般類繼承抽象類使用?override重寫 |
3 | 抽象方法聲明中使用?static?或?virtual?修飾符是錯誤的 |
? 3.1.3、abstract的使用場景
? ? ? ? 內容有通用的共性特征和行為,且必須要在不同的派生類實現(即:內容必須存在的時候用abstract)。
?3.2、virtual(虛擬)
virtual 關鍵字 - C# reference | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/virtual
? 【virtual
?】關鍵字用于修改方法、屬性、索引器或事件聲明,并使它們可以在派生類中被重寫。
? 3.2.1、虛方法
public class MyCar{public virtual string Name { get; set; }public virtual string Manufacturer { get; }public MyCar(string manufacturer){this.Manufacturer = manufacturer;}public virtual void Function(){Console.WriteLine($"【{Manufacturer}】品牌車況運行狀態良好");}public virtual Action<bool> Custom(bool start){if (start){Console.WriteLine($"【{Name}】儀表盤顯示發動機轉速");}return null;}}//Classpublic class SUVCar : MyCar{public SUVCar(string manufacturer) : base(manufacturer){}public override void Function(){base.Function();Console.WriteLine($"【{Manufacturer}】品牌開始校驗SUV的各個功能是否正常");}public override Action<bool> Custom(bool start){Action<bool> action=new Action<bool>(Test);Console.WriteLine($"【{Name}】所有功能準備完畢,開始出發");return action;}private void Test(bool start){if (start){Console.WriteLine("啟動智能駕駛功能");}}}//Class_endclass Program{static async Task Main(string[] args){MyCar car = new MyCar("自產");car.Name = "基礎車";car.Function();car.Custom(true);Console.WriteLine("---------------------------\r\n");car = new SUVCar("問界");car.Name = "SUV越野";car.Function();car.Custom(true);}}
序號 | 虛方法特點 |
1 | 虛方法必須有實現 |
2 | 虛方法可以不在派生類中重寫 |
虛方法的2中使用情況 | |
1 | 基類定義了virtual方法,但是派生類沒有重寫基類virtual方法,則對派生類的實例調用中,使用的是基類定義的virtual方法內容 |
2 | 基類定義了virtual方法,且派生類重寫了基類的virtual方法,則對派生類的實例調用中,使用的是派生類重寫的virtual方法內容 |
? 3.2.2、virual的使用場景
????????virtual的核心是多態【即:同一個方法能用不同的方式來做】;如:
1、支付方法Pay(),既可使用微信支付、也可使用支付寶支付或者其他方法支付;
2、消息發送方法MSGSend(),既可使用郵件發送、也可使用企業微信發送、或釘釘發送;
3.3、抽象方法與虛方法的區別與聯系
抽象方法與虛方法的相同點是:都使用override重寫。
序號 | 抽象方法(abstract) | 虛方法(virtual) |
1 | 抽象方法必須在抽象類中 | 沒有要求 |
2 | 抽象方法只是聲明沒有實際實現,必須在派生類中重寫實現 | 虛方法有聲明與實際實現,派生類可完全重寫、部分重寫或不重寫直接使用基類實現 |
3 | 抽象類不能被實例化(new),只能用實現了全部抽象方法的派生類來實例化 | 包含虛方法的類可以被實例化(new) |
?3.4、普通類、接口與抽象類
抽象類主要用于關系密切的對象;接口適合為不相關的類提供通用功能。
序號 | 普通類 | 接口 | 抽象類 |
1 | 普通類可有成員變量、常量、構造函數,沒有抽象方法 | 接口不能有常量、域、操作符、構造函數、析構函數及其任何靜態成員【可包含屬性、方法、索引和事件】 | 抽象類有抽象方法 |
2 | 普通類可繼承一個基類,多個接口 | 接口可繼承多個接口 | 抽象類也可繼承一個基類和多個接口 |
3 | 普通類可以定義具體的方法和實際實現 | 接口只能定義方法,而沒有具體實現 | 抽象類的抽象方法不能有具體實現 |
4 | 普通類成員沒有限制 | 接口成員必須是公共的 | 抽象類不能對private抽象 |
5 | 普通類可以實例化 | 接口不能實例化 | 抽象類不能實例化,只能使用實現了全部抽象方法的派生類來實例化 |
四、其他資料
訪問修飾符 - C# reference | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/access-modifiers
面向對象編程 - 封裝 - C# | Microsoft Learnhttps://learn.microsoft.com/zh-cn/dotnet/csharp/fundamentals/object-oriented/#encapsulation面向對象編程 - 繼承 - C# | Microsoft Learn
https://learn.microsoft.com/zh-cn/dotnet/csharp/fundamentals/object-oriented/inheritance面向對象編程 - 多態性 - C# | Microsoft Learn
https://learn.microsoft.com/zh-cn/dotnet/csharp/fundamentals/object-oriented/polymorphismC#面向對象的三大特性(封裝、繼承、多態)_c# 三大特性-CSDN博客文章瀏覽閱讀3.2k次,點贊3次,收藏43次。一、封裝 把客觀的事物封裝成類,并將類的內部實現隱藏,以保證數據的完整性;每個對象都包含了他能進行操作所需要的所有信息,因此對象不必依靠其他的對象來完成自己的操作。【優點】 1. 將變化隔離; 2. 便于使用; 3. 提高復用性; 4. 提高安全性;【封裝原則】 1. 將不需要對外提供的內容都隱藏起來; 2...._c# 三大特性
https://blog.csdn.net/xiaochenXIHUA/article/details/95037977
C#中抽象類和接口的區別與應用場景 https://www.cnblogs.com/yangzhou/p/3283994.html?搞了這么多年終于知道接口和抽象類的應用場景了
https://cloud.tencent.com/developer/article/1677833