Dot-Net

基類的實例怎麼能持有派生類的實例?

  • July 31, 2014

我已經是 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

引用自:https://stackoverflow.com/questions/8074320