2011-08-26 153 views
15

有人可以帮助我们了解下面的代码是否相同。如果不是类和interfance实例之间有什么区别。接口实例与类实例化

IUnityContainer container = new UnityContainer() 
UnityContainer container = new UnityContainer() 

据我所知,Inteface只有方法签名,如果接口已被3类实现。不太确定上述第一条语句将创建哪个实例。

谢谢。

回答

44

接口不能按定义实例化。你总是实例化一个具体的类。

所以在这两个陈述你的实例实际上是UnityContainer类型。

不同之处在于第一条语句,就C#而言,您的container实现了IUnityContainer,它可能有一个不同于UnityContainer的API。


考虑:

interface IAnimal 
{ 
    void die(); 
} 

class Cat : IAnimal 
{ 
    void die() { ... } 
    void meow() { ... } 
} 

现在:

IAnimal anAnimal = new Cat(); 
Cat aCat= new Cat(); 

C#糊涂账anAnimal.die()作品,因为die()IAnimal定义。但它不会让你做anAnimal.meow(),即使它是Cat,而aCat可以调用这两种方法。

当您使用界面作为您的类型时,您在某种程度上会丢失信息。

但是,如果你有其他类Dog也实现IAnimal,你anAnimal可以引用Dog实例为好。这是接口的力量;你可以给他们任何实现它的类。

+4

当你可以实例化一个接口时,有一个例外情况:它是一个COM接口。 – svick

+0

不错!我确信你的话“丢失信息”不打算使用接口降级。 –

+0

@Gert试图让它容易理解......结果更令人费解,我希望。 – NullUserException

3

真的没有“接口实例化”这样的东西,但有接口变量。第一行是一个这样的变量的例子。

在第一行中,您可以将container实例化为实现IUnityContainer的任何具体类。在第二行中,container对象只能从UnityContainer类或派生类实例化。

当您在代码中使用接口变量时,它允许您更轻松地切换出具体的实现,从而使您的代码更加灵活。

+0

这不是真的。 'UnityContainer'实现'IUnityContainer',所以你可以将第二个变量传递给接受'IUnityContainer'的方法。 – dlev

+1

第二个版本当然可以使用以'IUnityContainer'作为参数的方法。如果一个类实现了一些接口,它可以隐式转换为该接口。 – svick

+0

你说得对。我误解了这一点。不知道我在想什么...... – FishBasketGordo

0

编译器认为实例化并存储在IUnityContainer container变量中的对象只有在IUnityContainer接口中定义的成员。也就是说,如果UnityContainer类包含未由IUnityContainer接口定义的成员,则将无法调用它们。另一方面,您可以将任何实现IUnityContainer接口的对象“放入”IUnityContainer container变量中 - 而不仅仅是UnityContainer的实例。在第二个声明中,您坚持使用UnityContainer的实例以及继承层次结构中的对象。

查看C# Programming Guide to Interfaces了解更多关于接口的信息及其使用方法。

+0

当你说“属性”时,你可能是指“成员”。 – svick

+0

已更新。谢谢,@svick! –

0

接口实例化是不可能的。但是当我们使用它的实现类创建一个接口对象时,它就可以工作。

IUnityContainer container = new UnityContainer()// It is assigning an object of its implemented class. 
UnityContainer container = new UnityContainer() // To access directly by using like this. 

假设有一个多重继承,为了实现这一点,我们首先需要去。

有没有必要提供这样的事情,我们以第二种方式去。

接口限制直接访问数据及其类的成员。