2016-03-06 99 views
3

我有下面兩個類。在C#繼承層次結構中創建對象

enter image description here

當執行這條線,

Child myChildObj = new Child(); 

這是否創建單獨的兩個對象ParentChild? 或者只是一個子對象其中包含父方法和屬性

enter image description here

更新:我想知道在CLR,它是否真正在運行時創建一個Parent對象(無法訪問)。

我在tutorialspoint網站上看​​到以下引用。

派生類繼承基類成員變量和成員方法。 因此,應該在創建子類之前創建超類對象。您可以在成員初始化列表中給出超類初始化的說明。

我用下面的代碼來驗證這一點,我有兩個孩子和家長對象相同的hashCode值

Console.WriteLine("child object hashcode : "+this.GetHashCode()); 
Console.WriteLine("base object hashcode : "+base.GetHashCode()); 
+0

我不確定你的意思,你怎麼區分一個和兩個對象?您被賦予創建對象的單個引用,並且如您所知,該對象既可以用作「父」,也可以用作「子」。 – kai

+0

圖像添加了哪些信息?你不能只顯示類的定義嗎? – CodeCaster

+1

至於你的編輯:作者的意思是什麼_「因此,應該在創建子類之前創建超類對象,你可以在成員初始化列表中給出超類初始化指令」_也許是_「Call」:base( )'從你的構造函數調用超類的構造函數「_。這不是一個非常明確的說法。另外,關於哈希代碼:[_「GetHashCode始終返回相同的哈希代碼用於相同的對象引用」_](https://msdn.microsoft.com/zh-cn/library/11tbk3h9(v = vs.110).aspx ),所以'this.GetHashCode()'和'base.GetHashCode()'返回相同的結果。 – CodeCaster

回答

1

給出的答案都像你從書本學到的抽象的,我覺得你想知道它是什麼樣子下封面。你可以將子實例想象成一段內存,如果你要實例化一個父對象,只有一些額外的位和附加的子段(子位),你纔會得到這個內存。你得到的引用是一個指向開始的指針,那就是基類實例。這就是爲什麼沒有人會看到父實例和子實例之間的區別。因爲子實例是父實例(附加了子位)。這在你實例化GrandChild對象時繼續下去,這些也將與附加到它的額外位相同。現在你明白了爲什麼和什麼時候投射作品以及什麼時候會造成麻煩。

+0

你能否詳細解釋一下這個答案。 (使用圖表;因爲這是我真正想知道的)。請根據官方文件證明您的答案是正確的。 –

+0

官方文檔......也大寫。恐怕我沒有這些但是我自己也沒有補足,這是第三代編程語言繼承的基本實現。它不一定是實現它的唯一方法,但它是一種簡單,高效和直接的方式。對於編譯語言,我沒有看到任何實際的選擇,我相信這仍然是它的方式。我所說的位是數據字段和方法指針。對於虛擬方法而言,涉及額外的間接方向。 –

+0

尋找vtable和「虛擬方法表」,這應該提供一些鏈接來解釋這個東西在二進制級別。 –

3

這將創建一個包含兩種類型方法的Child類型的單個實例。您可以在創建的實例上調用這些方法。

0

它只創建一個「Child」類的實例。 「孩子」的實例從「父」類繼承(包括)所有成員。

2

ChildParent的子類,所以它繼承了它的所有屬性。但是當你創建一個Child的對象時,你只會得到一個Child的對象。沒有「第二部分」來照顧Parent相關的事情。內存中只存在一個對象。該單個對象的類型爲Child,因此也與Parent類型兼容。

0

只有一個可引用的對象是myChildObj。父類用作模板,但最終未實例化。該對象將擁有Parent類的所有成員變量和方法以及它自己的類中的變量和方法。

也可以使用多態這樣創建對象:

Parent obj = new Child();