近日為了工作需要,開始真正學習C#了,看了一遍教材《C#程式設計語言詳解》,作者Anders Hejlsberg親自編寫,語言並不華麗,卻如編譯器一般的嚴謹和邏輯。
看完之後有一些想不太明白的地方,一個個攻破。
第一個問題就是,沒有別的語言那些明顯的標記符,比如VB裡面的Function, Dim之類的。在C#裡不管是變數還是屬性,或者函數,都使用相同的聲明過程:public int SomeThing,如果後面加上小括弧,那麼就是一個函數。否則,如果帶有大括弧,那麼就是屬性,再否則,就是變數了。
而沒有這些修飾符之後,帶來了另一個問題,如果完成類的多態性。這個概念是類裡面最重要也最難理解的一個概念,找來找去,書上似乎沒有明確的提到這個文法。不過發現了幾個重要的詞,virtual, override, new。前兩個在看C++的時候已經見過了,這個new又是什麼呢?根據書上的說法和VS的提示,好像跟override有些想像。但是肯定是有區別的,於是寫段代碼研究一下。
使用經典的Human類作為基類,實現一個函數Walk,兩個子類Man和Woman,繼承這個類,分別實現這個函數Walk,不帶任何其它的開關符。Main函數裡使用
Human h1=new Man();
h1.Walk();
Human h2=new Woman();
h2.Walk();
來查看結果。如果基類裡面的函數沒有virtual修飾符,而且子類裡面的函數也不帶修飾符,那麼編譯器會報錯,提示加上new。OK,加上去,結果兩個函數顯示的都是執行了基類的Walk。這個似乎不太符合多態的定義。
於是在基類的函數上加上virtual,給兩個子類分別用override和new定義函數,再執行一遍。第一個程序呼叫了Man的Walk,這個是正確的多態過程。第二個程序呼叫的還是Human的Walk。
由此可以看出,new是給子類新增加了一個函數,可以說除了函數名字相同以外,它跟基類裡面的這個同名函數沒有任何關係。當使用子類的類型來調用的時候,它會運行子類中的函數,而如果類型是基類的話,被隱藏的基類函數就會站到前台來。只有使用virtual定義基類中的函數,並使用override標記子類中的函數,才可以達到想要的多態類。