2012-12-03 28 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