我知道接口不能被实例化,但如果我们将它分配给一个对象,任何人都可以解释内存如何分配给它。例如:内存分配接口
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