2012-12-03 24 views
2

我知道接口不能被實例化,但如果我們將它分配給一個對象,任何人都可以解釋內存如何分配給它。例如:內存分配接口

ITest obj = (ITest) new TestClass1(); //TestClass1 is a class which implements ITest 
obj.MethodsDefinedInInterface(); 

是否將ITest轉換爲對象以保存TestClass1的屬性和方法。

+1

想想這樣;一套建築圖紙在建築物中佔用多少空間?當然沒有;他們只用於建築,他們不是建築本身的一部分。類,接口和結構定義也是如此。只有物體需要記憶。 –

+0

感謝您的回覆。欣賞它。 – Sunny

+0

將界面視爲合同。如果一個對象實現並且接口。它實際上同意通過實施界面中描述的所有屬性/事件/方法來遵守合同。該接口本身不會構造,也不會分配任何內存。構建實例時的對象併爲其分配內存。 – Kevin

回答

4

之間沒有差別(在內存allocaton方面)我不知道你所說的 '分配' 的意思是什麼。以下語句使兩個不同的「分配」:

TestClass1 test = new TestClass1(); 

首先是new TestClass1()聲明,分配在堆上的sizeof(TestClass1)。其次,堆分配地址的分配存儲在變量test中,該變量作爲sizeof(object *)(即,IntPtr.Size,或基於正在運行的硬件+ OS +軟件的32/64位)在堆棧上分配)。

下面的語句是完全在「分配」相同:

ITest test = new TestClass1(); 

兩者之間唯一的區別是被叫做變量test可用的方法。

注意:這不適用於實現接口的結構。接口必須是一個引用類型,正如你所知,結構不是。這在.NET中被稱爲裝幀,並且通過首先將結構的副本放置在堆上,允許結構被引用,就像它是引用類型一樣。

所以我們現在重新評估聲明:

TestSTRUCT1 test2 = new TestSTRUCT1(); 

這堆在命名變量test2在 '分配' 的sizeof(TestSTRUCT1)。 (不知道分配給new TestSTRUCT1()的影響是什麼,它可能會創建一個額外的堆棧副本,但是應該立即在轉讓之後被去除

如果我們那麼這個值賦給接口:

ITest test3 = test2; 

我們現在做了兩個分配,首先將結構複製到堆中,然後將堆駐留結構的地址放置在新分配的變量test3(堆棧中)

1

內存獲取分配給像任何其他對象impliments接口的對象。無論它是否意味着接口只是對象的屬性

1

內存僅分配給TestClass1實例。接口ITest只是一種參考,它指向分配的內存。

+0

這不是事實。接口變量將導致內存分配給對象的實際實例的引用。引用需要非零的內存量。現在如果你一直在談論堆分配,那麼這可能適用,但這完全是一個不同的問題。 – Servy

+0

這就是我說的--OP在堆棧上有一個引用(分配的內存)(32位系統上的4個字節)。該引用是否具有類型「TestClass1」,「ITest」或「object」 –

2

它應該是類似於:

TestClass1 test = new TestClass1(); 
ITest obj = (ITest) test; 
obj.MethodsDefinedInInterface(); 

其中,我想,回答你的問題。

1

不ITEST轉換爲對象,以節省TestClass1

的屬性和方法ITEST是一種類型。 TestClass1屬性和方法仍然存在,只是你不能通過obj變量訪問它。

1

它非常簡單。您爲TestClass1分配然後將其轉回到接口。注意,你沒有實例化一個接口,你正在實例化一個實現接口的類,然後調用在具體類中實現的強制接口方法!

另一種方式把它是:

TestClass1 test = new TestClass1(); 
ITest obj = (ITest) test; 
obj.MethodsDefinedInInterface(); 

注意,分配的區域是TestClass1!它不會因爲演員而增長或縮小!

1

interfaces只需確保對象在編譯時在技術上和邏輯上都符合cerain標準。

當執行代碼並使用接口內存時,將分配內存,就好像您只是使用該類實例化對象一樣。

因此,有

ITest obj = (ITest) new TestClass1(); //TestClass1 is a class which implements ITest 
obj.MethodsDefinedInInterface(); 

TestClass1 obj = new TestClass1(); //TestClass1 is a class which implements ITest 
obj.MethodsDefinedInInterface(); 
1

因此, ,當你輸入這個方法的時候,空間將被分配到堆棧上的所有參數,如果適用的話,t他返回值(如果適用)以及該方法的所有局部變量。對於我們在這裏顯示的,唯一需要分配的局部變量是objobj是一個接口,因此需要足夠的空間用於單個參考(32位系統上的32位,64位系統上的64位)。由於沒有其他局部變量,返回值或參數,我們只會在堆棧中佔用一個字。

因爲我們分配一個對象(new TestClass1()),並假設對象是類(而不是struct,因爲命名structTestClass1會很平均值)有足夠的空間將在堆上分配給佔了TestClass的單個實例。該空間將爲每個單獨的字段提供足夠的空間(不管可訪問性),還有一些額外的空間用於某些對象開銷。對這個新分配的對象的引用將會被分配給我們本地變量的堆棧中。

這都是忽略處理器在運行時使用的寄存器;由於編譯器,抖動,操作系統,處理器硬件等的複雜轉換和優化,我無法開始嘗試預測會發生什麼。幸運的是,由於所有這些抽象,我並不需要關心。

+0

感謝您提供內存分配的低級別細節。 – Sunny