把new virtual override說透收藏

2022-03-02 11:21:57 字數 2855 閱讀 7653

我們先看下面一段程式:

/// 

/// 父類

/// 日期:2008-09-01

/// 

public

class

father

}/// 

/// 子類

/// 日期:2008-09-01

/// 

public

class

son:father

}class

program

}程式的執行結果是:

father.run0

father.run0

稍微細心的朋友可能發現在son類的run0方法下面有一段棕色的波浪線,當我們把滑鼠放到該下劃線上時,會看到下面的提示

(編譯程式時在程式的「輸出」視窗也能看到這個警告):

「methoddemo.son.run0()」隱藏了繼承的成員「methoddemo.father.run0()」。如果是有意隱藏,請使用關鍵字new。

如圖:然後我們再來第二個版本的run方法,我們稱之為run1(),,與第乙個版本的區別是在子類的同名同參(方法名相同,引數個數和引數順序相同,下同)方法前面加上了乙個new關鍵字,**如下:

/// 

/// 父類

/// 日期:2008-09-01    

/// 

public

class

father

}/// 

/// 子類

/// 日期:2008-09-01

/// 

public

class

son:father

}class

program

}執行結果如下:

father.run1

father.run1

我們發現加上new關鍵字之後,程式的執行結果沒有發生改變。也就是在c#中,如果在子類中有與父類同名同參的方法時,c#會隱式幫你在子類的方法前面新增乙個new關鍵字。

我們再寫第三個版本的run方法,即run2(),與第乙個版本不同的是父類的run2()方面前面加了乙個virtual關鍵字,表示這是乙個虛方法,子類的run2()除了與第乙個版本號不同之外(run0()改成run2())沒有什麼不同。

程式**如下:

/// 

/// 父類

/// 日期:2008-09-01

/// 

public

class

father

}/// 

/// 子類

/// 日期:2008-09-01

/// 

public

class

son:father

}class

program

}我們看看程式的執行效果:

father.run2

father.run2

程式執行效果與第乙個仍然沒有什麼區別,不過這次子類(son)的run2()方法又出現了與run方法的第乙個版本(run0())一樣的警告:「methoddemo.son.run2()」將隱藏繼承的成員「methoddemo.father.run2()」。若要使當前成員重寫該實現,請新增關鍵字override。否則,新增關鍵字new。

我們再寫第四個版本的run方法,我們稱之為run3(),這次父類中run3()的修飾符與第三個版本相比沒有變化(依然是virtual,虛方法),而子類son中的run3()方法與第三個版本相比多了乙個override修飾符(這次我們熟悉的那個棕色的波浪線警告沒有了)。**如下:

/// 

/// 父類

/// 日期:2008-09-01

/// 

public

class

father

}/// 

/// 子類

/// 日期:2008-09-01

/// 

public

class

son:father

}class

program

}程式的執行結果如下:

father.run3

son.run3

這次我們發現程式的執行結果與前面三次不一樣了,這次儘管我們宣告的物件型別都是father類(father數組裝的自然都是father型別的引用),但是因為例項化陣列中第二個元素的時候呼叫了son類的建構函式,也就是例項化了乙個father類的子類(我們知道子類可以當作父類來看待,他們之間是is a的關係,反之則不行),也就是說fatherlist陣列中的第二個元素的引用型別是father型別,但它的例項型別確實son型別。而在執行的時候,並不是根據我們的引用型別(引用型別是father型別的)去呼叫該引用型別的方法,而是呼叫該引用型別所指向的例項的方法。

為什麼會發生這些現象呢?這裡要提到兩個概念:早繫結(early binding)和晚繫結(late binding)。這個術語出現在存在繼承關係的基類和派生類中,它們同時定義了乙個同名同參的方法。

早繫結:在編譯的時候就已經確定了將來程式執行基類或是派生類的哪個方法。在編譯**的時候根據引用型別就決定了執行該引用型別中定義的方法,即基類的方法。這種方法執行效率高。

晚繫結:只有在執行的時候才能決定執行基類或者派生類中的哪個方法。執行的時候將根據該實際型別而不是引用型別來呼叫相關方法,即取決於我們new了什麼樣物件。也就是即使我們new乙個father類的子類son的例項,而不管我們是用father類的引用指向這個son的例項,方法呼叫的時候依然是呼叫son的方法,而不是father類的同名方法。

但是如果在基類中顯示宣告方法為虛方法,那麼clr在執行的時候會進行型別檢查,如果發現引用型別和實際的物件型別不一致,就會檢查派生類中是否覆蓋(override)了基類中的方法,如果是,則會執行派生類中的方法,而不是引用型別中的方法。

把心放平,把心放輕

把心放平,把心放輕,才會活的坦然,活的舒暢,活的快樂,活的安靜,活的真實,活的自然。把心放平,把心放輕,正確認識這個世界,看清這個世界。世界就是這樣,陽光與黑暗同在,美好與醜陋並存,我們要學會不只生活在陽光下,也要學會生活在陰暗裡,我們會看見鮮花,也會遭遇汙穢,我們會感受友愛,真情真愛永遠與我們同在...

把權力留給自己,把權力分給別人

對於與世無爭的人來說,權力是那樣的不值分文,但是當你揹負著責任的時候,權力就變成了不得不遵守的諾言。權力越大,壓力自然越大,有時候權力也會變成令人憎惡的東西。對於乙個管理者,把權力分給別人是一件很危險的事,因為你已經習慣並且能夠勝任運用你的權力,除非你遇到值得信賴的人。當然,很少有人願意一直握著權力...

把過去忘記

我非我,物非物 花非花,樹非樹 把酒當歌今日醉 且得開心且落寞早上忽然想明白了一件事情,不要生活在幻想中間,把過去忘記,轉身走開,是我最好的選擇 其實來北京工作不是我的本意,我可能更喜歡去深圳或者廣州一些,只是畢業的時候聽說我暗戀的某人要考北京的學校的研究生,於是我就衝了過來.只是陰差陽錯,我來了北...