不同於c++,沒有多重繼承,這是一件讓人感到開心的事……至少我是這樣認為的(多重繼承把代碼搞得不易於理解和調試,當然,多重繼承也有他的優勢,比如更加的靈活)。於是和JAVA一樣,當我們想多重的沿襲某某時,我們使用介面繼承,而普遍的繼承法方式則被稱為實現繼承。
· 在實現繼承中,有關於虛方法:virtual
· 按照c++的傳統,而是java的,一個方法在預設的情況下不是虛擬。注意,virtual只對於執行個體方法有作用!~
· c#要求在衍生類別重寫基類的方法時,需要使用 override 顯式的聲明!這裡,MS給出的理由是 在編程中,有“很多時候”,我們會因為一個小小失誤導致 方法的簽名與基類不同,從而無法重寫(一個新的方法被聲明)。額……這不是一個好理由,有了ItelliSence,這個應該不是問題吧……除非給出一個更為合理的解釋,否則我認為這不是一個好的改變!
· new關鍵字在隱藏方法上的使用,這裡的new並不是運算子……而是一個關鍵字。其目的是解決如下的問題:如果在衍生類別和基類中聲明了兩個簽名的方法,而這個方法沒有 virtual(基類)或者 override(衍生類別)修飾,那麼~基類的方法將會被隱藏!就是白寫了~是白寫了,白寫了,寫了,了……如果願意,我們最好重新命名~當然這是在二者完成完全不相關的功能的前提下!如果不這麼做,我們可以使用new關鍵字,讓他們不相關……;
說實話,對於基於這種目的而產生的文法,在我沒在實際中遇到,我永遠不會相信他的重要性,就比如new關鍵字,或許他的全部意義就在於,對於客戶,保證在你的新舊程式版本中調用方法的無痕……或許吧!
· base的使用,相當於 java的 super;在c#中,我們沒有用fuction = 0的形式去聲明一個純虛函數,於是abstract 抽象長生了,實現了幾乎相同的功能。 sealed關鍵字,相當於final
· 關於介面,interface,在我的理解的範圍之內,我是這樣來概括介面的:一種有著相同“通訊”協議 的對象的 組織形式。
根據對象不同特性,對象就會有很多中組織形式:比如,所有的對象都可以看作是object的執行個體……比如有些對象是派生自同一個類的執行個體。
對象之間的“通訊”靠的是他們的方法,當他們的(一部分)方法有些相同的制式的時候,我們就可以在通訊這個維度上來組織他們,例子先略掉。
· 在編寫不安全的程式碼的時候-----比如,把一個長類型(32位)強制轉化為短類型(16位,8位),資料可能會溢出,那麼我們使用checked 運算子,CLR會執行檢查,如果溢出,會拋出異常。uncheck是禁止溢出檢查的,在編譯的時候,給定編譯參數/checked,全部檢查~當然,會跳過unchecked檢查
· is 運算子,對象與類的相容性檢查;as運算子,顯示的類型轉化,但是用成不成功的問題,我覺得如果是有效as,應該是從基類到衍生類別的轉化……至少這個是一定成功的。
· 可空類型,int? a = null 有點像三態門……多了一種unknow狀態,有幾個比較規則:
在比較可空類型是,只要一個是null,結果就是false
還有一個狗血的空結合運算子,?? 確實夠狗血的!
· 類型轉換:什麼情況下可以隱式的轉換?不會造成資料的丟失的情況下~一般是可以進行隱式的轉換的。可空類型可隱式的轉換為可空,非可空->可空,可空不能隱士的到非可空,因為null沒法判定……
在可能有資料丟失的情況下,可以是使用顯示的類型轉換……
· boxing與unboxing 。裝箱用於描述把一個 實值型別 轉換為 一個參考型別……拆箱剛好相反。
關於裝箱的使用,讓我想起了cpp中的&,引用,在c#沒有了顯式的聲明一個實值型別的引用或者指標~so,裝箱的意義產生了。寫到這裡,我又聯想起前面的學習筆記中提到的ref 和out輸出參數,當時我寫到,二者的實現方式應該是相同,證據之一是不能用out,ref作為函數簽名。到這裡,我在進一步,ref out的實現方式應該是boxing……
顯而易見,拆箱的時候可能有溢出~誰知道箱子裡面會不會i有彈簧蛇……
· 對象的相等比較:那麼大致可以分為深度和淺度兩種嘍……很糾結於混亂的東西~我倒是覺得object中的幾個方法除了那個virtual不提,其他兩個沒啥營養……
· 下面就是傳說中的文法糖 sytax suger~運算子多載……不過在c#中。我可不認為這僅僅是糖這麼簡單。
在c#中所有的運算子多載都需要聲明為public與static,目的是脫離執行個體與類相關的。這也到省去了c++operator是不是成員函數的煩惱。而且說實話,我覺得friend的存在,本身就是違背OO思想的。這個簡化與嚴格化,不錯~
對於比較子,需要成對的重載,比如,重載了==就也要重載!=
· 自訂資料類型轉換:這也是一種運算子多載,所以~要遵循上述的原則。在聲明的是有 implicit 與 explicit 之分
值得關注的是 多重資料類型轉換,起大致的意義在於,編譯器了可以在已知的類型中進行自適應的轉換。
比如我們定義了如下的隱式轉換
view plaincopy to clipboardprint?public static implicit operator int(MyClass mc) { //something I will do } public static implicit operator int(MyClass mc)
{
//something I will do
} view plaincopy to clipboardprint?MyClass test = new MyClass(); int i = 5 + MyClass; MyClass test = new MyClass();
int i = 5 + MyClass;
這樣是可以的,(編譯器?)應該會選擇一條精確度損失最小的路線(這是我估計的判定規則)來 進行轉換,因為這裡只有一條,即:MyClass->float->int
Ok~這一篇 Over