多态性(C#)
? ? ? 在面向對象編程中繼承性和多態性是重要機制,前面我為大家分享了我對“類的繼承”的理解,哪么今天我就跟大家分享下我對“多態性(C#)”的理解。
? ? ? 首先我們先來看看多態的定義,同一操作作用于不同的對象,可以有不同的解釋,產生不同的執行結果。
? ? ? C#中多態分為兩種形式,一種是編譯的多態,一種是運行的多態;而所涉及到多態的有重載、重寫、虛方法、抽象方法和隱藏方法。
? ? ? 下面來看看這一段代碼,我們從代碼中來分析他們的概念及區別:
? ?public abstract class A
? {
? ? ? ? ?public abstract void prind();
? }
? public class B:A
? ? ? {
? ? ? ? ? ?public override void prind()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? Console.WriteLine("我是B類,我重寫了A類的抽象方法prind()");
? ? ? ? ? ? }
? ? ? ? ? ? public virtual void Bprind()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ?Console.WriteLine("我是B類中的虛方法,我可以被繼承B類的派生類重寫");
? ? ? ? ? ? }
? ? ? ? ? ? public void Nprind()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? Console.WriteLine("Nprind");
? ? ? ? ? ? }
? ?}
? ?public class C:B
? ?{
? ? ? ? ?public override Bprind()
? ? ? ? ?{
? ? ? ? ? ? ? Console.WriteLine("我重寫了B類的虛方法Bprind");
? ? ? ? ?}
? ? ? ? ? new ?public void Nprind()
? ? ? ? ? {
? ? ? ? ? ? ? ? Console.WriteLine("我是隱藏Nprind");
? ? ? ? ? }
? ? ? ? ?/*?下面是另一種隱藏方法的表現形式
? ? ? ? ? public new void Nprind()
? ? ? ? ? {
? ? ? ? ? ? ? ? Console.WriteLine("我是隱藏Nprind");
? ? ? ? ? }
? ? ? ? ?*/
? ? ? ? ? public void Cprind()
? ? ? ? ?{
? ? ? ? ? ? ? ?Console.WriteLine("我是Cprind方法");
? ? ? ? ?}
? ? ? ? ?public void Cprind(string str)
? ? ? ? ?{
? ? ? ? ? ? ? ?Console.WriteLine(str+"我被重載了");
? ? ? ? ?}
? ? }
? ? class D
? ? {
? ? ? ? ?static void Main(string []arge)
? ? ? ? ?{ ?
? ? ? ? ? ? ? B b=new B();
? ? ? ? ? ? ? B bc=new C();
? ? ? ? ? ? ? C c=new C();
? ? ? ? ? ? ?//重寫抽象方法
? ? ? ? ? ? ? b.prind();
? ? ? ? ? ? ?//重寫虛方法
? ? ? ? ? ? ? b.Bprind();
? ? ? ? ? ? ? bc.Bprind();
? ? ? ? ? ? ?//隱藏方法
? ? ? ? ? ? ? b.Nprind();
? ? ? ? ? ? ? bc.Nprind();
? ? ? ? ? ? ? c.Nprind();
? ? ? ? ? ? ?//重載
? ? ? ? ? ? ? bc.Cprind();
? ? ? ? ? ? ? bc.Cprind("E");
? ? ? ? ? ? ? Console.Read();
? ? ? ? ?}
? ? }
輸出結果:
我是B類,我重寫了A類的抽象方法prind()
我是B類中的虛方法,我可以被繼承B類的派生類重寫
我重寫了B類的虛方法Bprind
Nprind
Nprind
我是隱藏Nprind
我是Cprind方法
E我被重載了
如果單看這段代碼可能會看的很費力,所以我們來聽聽類他們之間的對話。
D:A類因為你是抽象類,所以你可以定義抽象方法,定義的抽象方法prind可以被繼承你的子類重寫;因此B類可以重寫你的抽象方法prind。
A:我可以被繼承我的子類B重寫,哪么我也可以被其他的子類重寫咯,也就是說我使用了多態性。
D:是的你使用了多態性中涉及的抽象方法,因為你的所有子類都可以對你的抽象方法重寫,所以你符合了多態性的定義;但你的所有子類都要注意,重寫你的抽象方法必須要用到override關鍵字、修飾符要相同、傳遞的參數個數和類型也都要一樣及方法的返回值都要一樣。
?
D:B類你自身的Bprind方法是虛方法也可以被繼承你的子類重寫,不過你和A類不同的是,你自身也可以調用這個虛方法。
B:為什么Bprind會是虛方法呢?它和別的方法也沒什么不同啊,只是多了個virtual關鍵字而已,難道加了virtual關鍵字的就是虛方法?
D:對的,虛方法就是必須要加上virtual關鍵字,而沒有加virtual或別的關鍵字的我們叫它為非虛方法;也是因為是虛方法才可以重寫,非虛方法是不能重寫的;但要注意只有繼承你的子類才可以重寫你的虛方法。
B:哦,所以C類可以重寫我的Bprind這個虛方法。
?
D:C類你不但重寫了父類B的虛方法,還把B類中的Nprind方法寫在了隱藏方法了,而已還對自身的Cprind方法進行了重載。
C:聽到你跟A、B類的對話我知道了我是重寫了虛方法,但這個隱藏方法和重載了Cprind方法,又是什么回事呢?
D:隱藏方法和重寫方法差不多,只是關鍵字不是override,而改成了new;還有不同的是new可以在修飾符前或后。而重載是在同一個作用域中使用了相同的方法名,修飾符、返回值、參數都可以不相同。
C:隱藏方法我自己能調用吧,但如果實例化父類時引用的是我,哪么調用的應該是我的還是父類的方法呢?
D:隱藏方法你自己可以,但只有是對你自己實例時調用的才是你,而如果父類實例時引用的是你,哪么調用的將是父類的方法。
?
? ? ? 首先我們先從他們對話和給合代碼來看看,重載與重寫的區別:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 重載: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 重寫:
? ? ? ? ? ? ?修飾符 ? ? ? ? ? ? ? ? ? ?可以不同 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?必須相同 ? ? ? ? ? ? ? ? ? ? ??
? ? ? ?參數個數及類型 ? ? ? ? ? ? ? 可以不同 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?必須相同
? ? ? ? ? ? 返回值 ? ? ? ? ? ? ? ? ? ? 可以不同 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?必須相同
? ? ? ? ? ? 方法名 ? ? ? ? ? ? ? ? ? ? 必須相同 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?必須相同
?
? ? ? 接下來我們來看看抽象方法、隱藏方法、虛方法的注意事項:
? ? ? ?抽象方法:
? ? ? ?1.在基類中定義,派生類中重寫。
? ? ? ?2.抽象方法只有在抽象類中才可使用。
? ? ? ?3.抽象類不能實例化。
? ? ? ?4.必須使用abstract。
? ? ? ?隱藏方法:
? ? ? ?1.派生類中定義的和基類中的某個方法名相同。
? ? ? ?2.父類調用父類的方法,而子類調用子類的方法。
? ? ? ?3.使用new關鍵字,虛方法也能使用。
? ? ? ? 虛方法:
? ? ? ? 1.在父類中定義的,子類可以重寫。
? ? ? ? 2.使用virtual關鍵字。
? ? ? ? 注:父類自身也可調用。
?
轉載于:https://www.cnblogs.com/ljhboke/p/5047011.html
總結
- 上一篇: Unity3d 配置OpenCV(Emg
- 下一篇: [ExtJS5学习笔记]第三十五条 se