4

我知道接口不能被实例化,但是如果我们将它分配给一个对象,谁能解释一下内存是如何分配给它的。例如:

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

ITest 是否转换为对象以保存 TestClass1 的属性和方法。

4

8 回答 8

7

我不确定您所说的“分配”到底是什么意思。以下语句进行了两个单独的“分配”:

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();

这在命名变量的堆栈上“分配” sizeof(TestSTRUCT1) test2。(不确定分配的影响是什么new TestSTRUCT1(),它可能会创建一个额外的堆栈副本,但应在分配后立即删除。

如果我们然后将此值分配给接口:

ITest test3 = test2;

我们现在又进行了两次分配。首先将结构复制到堆中。然后该堆驻留结构的地址被放置在一个新的“分配”变量test3中(在堆栈上)。

于 2012-12-03T19:54:13.920 回答
2

它应该类似于:

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

我认为,这回答了你的问题。

于 2012-12-03T19:37:42.087 回答
1

因此,首先,当您进入此方法时,将在堆栈上为所有参数分配空间(如果适用),返回值(如果适用)以及该方法的所有局部变量。对于我们在这里展示的内容,唯一需要分配的局部变量是obj. obj是一个接口,因此需要足够的空间用于单个引用(3​​2 位系统上为 32 位,64 位系统上为 64 位)。由于没有其他局部变量、返回值或参数,我们将只占用堆栈上的那个单词。

因为我们正在分配单个对象 ( new TestClass1()) 并假设该对象是一个类(而不是 a struct,因为命名 astruct TestClass1会非常卑鄙)将在堆上分配足够的空间来解释TestClass. 该空间将足以容纳每个字段(无论可访问性如何),再加上一些额外的对象开销。对这个新分配的对象的引用将进入为我们的局部变量分配的堆栈中的位置。

这都忽略了处理器在运行时使用的寄存器;由于编译器、抖动、操作系统、处理器硬件等的复杂转换和优化。我无法开始尝试预测会发生什么。幸运的是,由于所有这些抽象,我真的不需要关心。

于 2012-12-03T19:59:13.800 回答
1

像任何其他对象一样为实现接口的对象分配内存。它是否暗示一个接口只是对象的一个​​属性

于 2012-12-03T19:37:08.920 回答
1

TestClass1例如分配内存。接口ITest只是一种引用类型,它指向分配的内存。

于 2012-12-03T19:37:13.440 回答
1

ITest 是否转换为对象以保存 TestClass1 的属性和方法

ITest 是一种类型。TestClass1 属性和方法仍然存在,只是您无法通过 obj 变量访问它。

于 2012-12-03T19:38:18.700 回答
1

它非常简单。您为 TestClass1 分配,然后将其转换回接口。请注意,您不是在实例化一个接口,而是在实例化一个实现该接口的类,然后调用在具体类中实现(强制)的接口方法!

另一种说法是:

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

请注意,分配的区域是为 TestClass1!它不会因为演员而增长或缩小!

于 2012-12-03T19:38:23.600 回答
1

interfaces只需确保对象在编译时在技术上和逻辑上都满足某些标准。

当执行代码并使用接口时,内存将被分配,就好像你只是使用类来实例化对象一样。

所以两者之间没有区别(就内存分配而言)

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();
于 2012-12-03T19:38:40.017 回答