在C#
中,我们可以继承多个接口。在这种情况下,如果创建了一个对象,它只是隐藏属性或方法,还是编译器会避免创建和内存分配给其他接口的那些?例如,我有两个接口和一个类如下
interface IExample1
{
void E1Test1();
void E1Test2();
}
interface IExample2
{
void E2Test1();
void E2Test2();
}
class Example : IExample1, IExample2
{
public void E1Test1()
{
throw new NotImplementedException();
}
public void E1Test2()
{
throw new NotImplementedException();
}
public void E2Test1()
{
throw new NotImplementedException();
}
public void E2Test2()
{
throw new NotImplementedException();
}
}
当我创建像
这样的对象时IExample1 IE1 = new Example();
IExample2 IE2 = new Example();
编译器是否会为包括所有方法在内的两个接口创建完整对象,并将其隐藏为无法访问的接口?或者它只是使用可用于特定界面的方法创建?
答案 0 :(得分:8)
当您使用其构造函数(使用new ...
之后)实例化类时,总是内存中该clas的完整实例。没有接口的实例。
另一方面的界面只是该实例上的某种视图。因此,在您的示例中,您的实例上有四个都存在的方法。但是,您可能会也可能不会从IExample1
或IExample2
类型的引用访问这些方法。例如。虽然底层的实例确实有这种方法,但你不能在E2Test1
类型的引用上IExample1
:
IExample1 i1 = new Example();
现在调用i1.E1Test1()
将编译得很好,而i1.E2Test1()
则不会,因为该方法是在另一个接口上定义的。但是,您可以简单地将i1
引用的实例转换为另一个接口,并以这种方式访问该成员:
IExample i2 = (IExample2) i1;
i2.E2Test1();
编辑从TimSchmelters评论:如果你的Example
- 类只实现IExample1
而不是其他接口转换为那个肯定会失败并在运行时产生InvalidCastException
。因此,在这种情况下,Example
- 类的实例只会在IExample1
上定义成员,而不会在IExample2
上定义成员。然后投射到后者是没有意义的。
答案 1 :(得分:3)
您正在堆上创建Example
对象。它具有Example
具有的所有内容。例如,你可以这样做。
IExample1 IE1 = new Example();
IExample2 IE2 = new Example();
IExample2 casted = (IExample1)IE1;
您还可以调试并看到IE1
和IE2
实际上是Example
个实例。
答案 2 :(得分:2)
这些方法属于类的实例。该实例是对象。 您只能从具体类型(例如类)创建新实例。 您无法从抽象类型(抽象类或接口)创建新实例。
因此得出结论,当你使用new()创建时,你将拥有新实例中的所有方法。
此外: 您可以通过3种方式查看新对象(如示例中所示):
结论:您创建的对象是相同的(新的Example()),但只有您查看它的方式会发生变化。
提示:阅读隐式和显式接口实现