我知道接口不能被實例化,但如果我們將它分配給一個對象,任何人都可以解釋內存如何分配給它。例如:內存分配接口
ITest obj = (ITest) new TestClass1(); //TestClass1 is a class which implements ITest
obj.MethodsDefinedInInterface();
是否將ITest轉換爲對象以保存TestClass1的屬性和方法。
我知道接口不能被實例化,但如果我們將它分配給一個對象,任何人都可以解釋內存如何分配給它。例如:內存分配接口
ITest obj = (ITest) new TestClass1(); //TestClass1 is a class which implements ITest
obj.MethodsDefinedInInterface();
是否將ITest轉換爲對象以保存TestClass1的屬性和方法。
之間沒有差別(在內存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
(堆棧中)
內存獲取分配給像任何其他對象impliments接口的對象。無論它是否意味着接口只是對象的屬性
內存僅分配給TestClass1
實例。接口ITest
只是一種參考,它指向分配的內存。
這不是事實。接口變量將導致內存分配給對象的實際實例的引用。引用需要非零的內存量。現在如果你一直在談論堆分配,那麼這可能適用,但這完全是一個不同的問題。 – Servy
這就是我說的--OP在堆棧上有一個引用(分配的內存)(32位系統上的4個字節)。該引用是否具有類型「TestClass1」,「ITest」或「object」 –
它應該是類似於:
TestClass1 test = new TestClass1();
ITest obj = (ITest) test;
obj.MethodsDefinedInInterface();
其中,我想,回答你的問題。
不ITEST轉換爲對象,以節省TestClass1
的屬性和方法ITEST是一種類型。 TestClass1屬性和方法仍然存在,只是你不能通過obj變量訪問它。
它非常簡單。您爲TestClass1分配然後將其轉回到接口。注意,你沒有實例化一個接口,你正在實例化一個實現接口的類,然後調用在具體類中實現的強制接口方法!
另一種方式把它是:
TestClass1 test = new TestClass1();
ITest obj = (ITest) test;
obj.MethodsDefinedInInterface();
注意,分配的區域是TestClass1!它不會因爲演員而增長或縮小!
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();
因此, ,當你輸入這個方法的時候,空間將被分配到堆棧上的所有參數,如果適用的話,t他返回值(如果適用)以及該方法的所有局部變量。對於我們在這裏顯示的,唯一需要分配的局部變量是obj
。 obj
是一個接口,因此需要足夠的空間用於單個參考(32位系統上的32位,64位系統上的64位)。由於沒有其他局部變量,返回值或參數,我們只會在堆棧中佔用一個字。
因爲我們分配一個對象(new TestClass1()
),並假設對象是類(而不是struct
,因爲命名struct
TestClass1
會很平均值)有足夠的空間將在堆上分配給佔了TestClass
的單個實例。該空間將爲每個單獨的字段提供足夠的空間(不管可訪問性),還有一些額外的空間用於某些對象開銷。對這個新分配的對象的引用將會被分配給我們本地變量的堆棧中。
這都是忽略處理器在運行時使用的寄存器;由於編譯器,抖動,操作系統,處理器硬件等的複雜轉換和優化,我無法開始嘗試預測會發生什麼。幸運的是,由於所有這些抽象,我並不需要關心。
感謝您提供內存分配的低級別細節。 – Sunny
想想這樣;一套建築圖紙在建築物中佔用多少空間?當然沒有;他們只用於建築,他們不是建築本身的一部分。類,接口和結構定義也是如此。只有物體需要記憶。 –
感謝您的回覆。欣賞它。 – Sunny
將界面視爲合同。如果一個對象實現並且接口。它實際上同意通過實施界面中描述的所有屬性/事件/方法來遵守合同。該接口本身不會構造,也不會分配任何內存。構建實例時的對象併爲其分配內存。 – Kevin