virtual和override
偶然間看到的題,借此記錄。
class Program{static void Main(string[] args){D d = new D(); //第一個(gè)D是申明類,第二個(gè)D是實(shí)例類A a = d;B b = d;C c = d;a.F();b.F();c.F();d.F();}class A{public virtual void F() { Console.WriteLine("A.F"); }}class B : A{public override void F() { Console.WriteLine("B.F"); }}class C : B{public virtual void F() { Console.WriteLine("C.F"); }}class D : C{public override void F() { Console.WriteLine("D.F"); }}}輸出結(jié)果:
下面記錄一下解題步驟:
a.F();? >>>? 1. 檢查申明類A 2. 是虛方法 3. 繼續(xù)檢查實(shí)例類D 4. 有重寫,但是相對于類A來說Fun()在類C中被new 過,根據(jù)口訣“new則看類型,override只管新” 5. 繼續(xù)檢查父類B 6. 類B中override了父類A的 Fun() 7. 執(zhí)行類B中的Fun(),輸出B.F
b.F();? >>>? 1. 檢查申明類B 2. 不是虛方法 3. 直接執(zhí)行類B中的Fun(),輸出B.F
c.F();? >>>? 1. 檢查申明類C 2. 是虛方法 3. 繼續(xù)檢查實(shí)例類D 4. 有重寫,類D重寫了類C中的Fun(),根據(jù)口訣“new則看類型,override只管新” 5. 執(zhí)行類D中的Fun(),輸出D.F
d.F();? >>>? 1. 檢查申明類D 2. 不是虛方法 3. 直接執(zhí)行類D中的Fun(),輸出D.F
摘用一下別人特別好的總結(jié):
具體的檢查的流程如下
1、當(dāng)調(diào)用一個(gè)對象的函數(shù)時(shí),系統(tǒng)會(huì)直接去檢查這個(gè)對象申明定義的類,即申明類,看所調(diào)用的函數(shù)是否為虛函數(shù);
2、如果不是虛函數(shù),那么它就直接執(zhí)行該函數(shù)。而如果有virtual關(guān)鍵字,也就是一個(gè)虛函數(shù),那么這個(gè)時(shí)候它就不會(huì)立刻執(zhí)行該函數(shù)了,而是轉(zhuǎn)去檢查對象的實(shí)例類。
3、在這個(gè)實(shí)例類里,他會(huì)檢查這個(gè)實(shí)例類的定義中是否有重新實(shí)現(xiàn)該虛函數(shù)(通過override關(guān)鍵字),如果是有,那么OK,它就不會(huì)再找了,而馬上執(zhí)行該實(shí)例類中的這個(gè)重新實(shí)現(xiàn)的函數(shù)。而如果沒有的話,系統(tǒng)就會(huì)不停地往上找實(shí)例類的父類,并對父類重復(fù)剛才在實(shí)例類里的檢查,直到找到第一個(gè)重載了該虛函數(shù)的父類為止,然后執(zhí)行該父類里重載后的函數(shù)。
?在上面的規(guī)則中,可以看到,如果子類沒有override的修飾,那么就算父類是virtual的方法,子類的方法也無法被調(diào)用,而會(huì)去它的父類中找override的方法,直到找到祖先類。所以在面向?qū)ο蟮拈_發(fā)過程中,如果要實(shí)現(xiàn)Dependency Injection、IoC等設(shè)計(jì)模式,就必須非常留意類設(shè)計(jì)中繼承方法的聲明,否則很可能導(dǎo)致實(shí)際的程序運(yùn)行與預(yù)期不符。
?引用:https://www.cnblogs.com/yanyao/p/4830768.html
轉(zhuǎn)載于:https://www.cnblogs.com/ZCrystal/p/11008409.html
總結(jié)
以上是生活随笔為你收集整理的virtual和override的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多囊卵巢综合征能做试管婴儿吗
- 下一篇: Codeforces 1182A Fi