Dot-Net
基類的實例怎麼能持有派生類的實例?
我已經是 2 年的 .Net 編碼器(不能說我是程序員)。多年來我無法理解一個問題,那就是基類的實例如何擁有派生類的實例?
假設我們有兩個類:
class BaseClass { public A propertyA; public B propertyB; } class DerivedClass :BaseClass { public C propertyC; }怎麼會這樣:
BaseClass obj = new DerivedClass ()我的意思是, 的記憶體模型
BaseClass沒有空間容納新添加的propertyC,那它怎麼還能保存propertyC的值呢?另一方面,這怎麼可能發生:
DerivedClass obj = new BaseClass()我認為這是正確的方法,因為記憶體模型
DerivedClass具有 BaseClass 的所有空間,甚至更多。但這不是真的,為什麼?我知道我在問一個非常愚蠢的問題,但是有人可以給我一個更詳細的答案嗎?從記憶體或編譯器的角度來看會更好。
因為(而且這個概念經常被誤解)保存指針的變數的類型獨立於它所指向的對象的實際具體類型。
所以當你寫
BaseClass obj = new DerivedClass ()說的部分在 Stack 上
BaseClass obj創建一個新的引用變數,編譯器理解該變數保存對來自或派生的東西的引用BaseClass。讀取的部分
= new DerivedClass ()實際上創建了一個type的新對象DerivedClass,將其儲存在堆中,並將指向該對象的指針儲存在指向的記憶體位置中obj。堆上的 實際對像是DerivedClass; 這被稱為對象的具體類型。該變數
obj被聲明為類型BaseClass。這不是一個具體的類型,它只是一個變數類型,它只限制編譯器將地址儲存到指向不是 aBaseClass或不是從該類型派生的對象的變數中BaseClass。這樣做是為了保證您放入 obj 變數中的任何內容,無論它是
BaseClassor的具體類型DerivedClass,它都將具有該類型的所有方法、屬性和其他成員BaseClass。它告訴編譯器該obj變數的所有使用都應僅限於類的那些成員的使用BaseClass。