C#類中方法的執(zhí)行順序是什么
有些中級開發(fā)小伙伴還是搞不太明白在繼承父類以及不同場景實例化的情況下,父類和子類的各種方法的執(zhí)行順序到底是什么,下面通過場景的舉例來重新認(rèn)識下方法的執(zhí)行順序:
(下面內(nèi)容涉及到了C#中的繼承,構(gòu)造函數(shù),虛方法,虛方法的重寫,new關(guān)鍵字等知識點)
場景一
有子類繼承,但是只實例化父類:只執(zhí)行A對象,輸出A對象的信息
class A { public A() => Console.WriteLine("A的構(gòu)造函數(shù)"); public virtual void Fun() => Console.WriteLine("A的方法"); } class B : A { public B() => Console.WriteLine("B的構(gòu)造函數(shù)"); public void Fun() => Console.WriteLine("B的方法"); } class Program { static void Main(string[] args) { A a = new A(); a.Fun(); Console.ReadLine(); } }
上述Main方法中在new A對象時,程序首先進(jìn)入class A中,執(zhí)行class A的構(gòu)造函數(shù)A(),然后執(zhí)行class A中的Fun()方法,故運行結(jié)果為:
場景二
實例化子類,子類和父類的構(gòu)造函數(shù)的執(zhí)行順序:當(dāng)執(zhí)行B對象時,因為繼承A對象,所以首先執(zhí)行基類A的構(gòu)造函數(shù)
class A { public A() => Console.WriteLine("A的構(gòu)造函數(shù)"); public virtual void Fun()=> Console.WriteLine("A的方法"); } class B : A { public B() => Console.WriteLine("B的構(gòu)造函數(shù)"); public void Fun() => Console.WriteLine("B的方法"); } class Program { static void Main(string[] args) { B b = new B(); b.Fun(); Console.ReadKey(); } }
上述Main方法中在new B對象時,由于B繼承A,先執(zhí)行父類的構(gòu)造函數(shù),所以先執(zhí)行A中的構(gòu)造函數(shù)A(),然后在執(zhí)行B中的構(gòu)造函數(shù)B(),故運行結(jié)果為:
場景三
父類有虛方法,子類沒有使用(override)關(guān)鍵字重寫父類方法的時候,使用的是new關(guān)鍵字時:
class A { public A()=> Console.WriteLine("A的構(gòu)造函數(shù)"); public virtual void Fun() => Console.WriteLine("A的方法"); } class B : A { public B() => Console.WriteLine("B的構(gòu)造函數(shù)"); //不寫new時,該方法會拋出警告,但不是錯誤 public new void Fun()=> Console.WriteLine("B的方法"); } class Program { static void Main(string[] args) { A a = new B(); a.Fun(); Console.ReadKey(); } }
上述Main方法中先new B對象,先執(zhí)行A中的構(gòu)造函數(shù)A(),然后在執(zhí)行B中的構(gòu)造函數(shù)B(),最后調(diào)用class A的Fun()方法(沒有重寫父類方法),故運行結(jié)果為:
場景四
父類有虛方法, 當(dāng)子類重寫了(override)父類的方法時:
class A { public A()=> Console.WriteLine("A的構(gòu)造函數(shù)"); public virtual void Fun() => Console.WriteLine("A的方法"); } class B : A { public B()=> Console.WriteLine("B的構(gòu)造函數(shù)"); public override void Fun()=> Console.WriteLine("B的方法"); } static void Main(string[] args) { A a = new B(); a.Fun(); Console.ReadKey(); }
上述Main方法同樣是先new B對象,先執(zhí)行A中的構(gòu)造函數(shù)A(),然后在執(zhí)行B中的構(gòu)造函數(shù)B(),但是子方法中使用了override關(guān)鍵字“覆蓋”,使得子類中方法覆蓋了父類中的方法,無法再訪問父類中原始方法。(要重寫方法,父類方法必須有virtual關(guān)鍵字),所以其運行結(jié)果為:
場景五
基類是接口層,多重繼承時:
interface I { void Fun(); } class A : I { public A() => Console.WriteLine("A的構(gòu)造函數(shù)"); public virtual void Fun() => Console.WriteLine("A的方法"); } class B : A { public B() => Console.WriteLine("B的構(gòu)造函數(shù)"); //不寫new時,該方法會拋出警告 public new void Fun() =>Console.WriteLine("B的方法"); } static void Main(string[] args) { B b = new B(); b.Fun(); ((A)b).Fun(); ((I)b).Fun(); Console.ReadKey(); }
打印結(jié)果:
場景六
當(dāng)多重繼承,子類重寫override父類方法時:
interface I { void Fun(); } class A : I { public A() => Console.WriteLine("A的構(gòu)造函數(shù)"); public virtual void Fun() => Console.WriteLine("A的方法"); } class B : A { public B() => Console.WriteLine("B的構(gòu)造函數(shù)"); public override void Fun() =>Console.WriteLine("B的方法"); } static void Main(string[] args) { B b = new B(); b.Fun(); ((A)b).Fun(); ((I)b).Fun(); Console.ReadKey(); }
打印結(jié)果:(對比場景5)
場景七
使用new重寫父類方法,同時讓每個子類都繼承接口:
interface I { void Fun(); } class A : I { public A() => Console.WriteLine("A的構(gòu)造函數(shù)"); public virtual void Fun() => Console.WriteLine("A的方法"); } class B : A, I { public B() => Console.WriteLine("B的構(gòu)造函數(shù)"); //不寫new時,該方法會拋出警告 public new void Fun() => Console.WriteLine("B的方法"); } static void Main(string[] args) { B b = new B(); b.Fun(); ((A)b).Fun(); ((I)b).Fun(); Console.ReadKey(); }
打印結(jié)果:
到此這篇關(guān)于C#類中方法的執(zhí)行順序是什么的文章就介紹到這了,更多相關(guān)C#類中方法的執(zhí)行順序 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c# 動態(tài)加載dll文件,并實現(xiàn)調(diào)用其中的方法(推薦)
下面小編就為大家?guī)硪黄猚# 動態(tài)加載dll文件,并實現(xiàn)調(diào)用其中的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02