2011-08-26 14 views
15

Podría alguien ayudarme a entender si los siguientes códigos son los mismos. Si no, ¿cuál es la diferencia entre instanciación de clase e interfance?Instanciación de interfaz frente a instanciación de clase

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

En lo que a entender Inteface sólo tiene firma del método y si la interfaz ha sido implementado por 3 clases. No estoy seguro de cuál de las tres instancias se crearía en la primera declaración anterior.

Gracias.

Respuesta

44

Las interfaces no se pueden crear instancias por definición. Siempre crea una instancia de una clase concreta.

Por lo tanto, en ambas declaraciones su instancia es en realidad del tipo UnityContainer.

La diferencia es que la primera sentencia, en lo que se refiere a C#, su container es algo que implementa IUnityContainer, lo que podría tener una API diferente de UnityContainer.


considerar:

interface IAnimal 
{ 
    void die(); 
} 

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

Ahora:

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

C# sabe a ciencia cierta anAnimal.die() obras, porque die() se define en IAnimal. Pero no le permitirá hacer anAnimal.meow() aunque sea Cat, mientras que aCat puede invocar ambos métodos.

Cuando utiliza la interfaz como su tipo, de alguna manera está perdiendo información.

Sin embargo, si tuviera otra clase Dog que también implementa IAnimal, su anAnimal podría hacer referencia a una instancia Dog también. Ese es el poder de una interfaz; puedes darles cualquier clase que lo implemente.

+4

Hay un caso excepcional cuando * puedes * crear una instancia de una interfaz: cuando se trata de una interfaz COM. – svick

+0

¡Agradable! Estoy seguro de que sus palabras "perder información" no pretenden degradar el uso de interfaces. –

+0

@Gert Tratando de que sea fácil de entender ... El resultado es más enrevesado de lo que esperaba. – NullUserException

3

Realmente no existe la "creación de instancias de interfaz", pero existen variables de interfaz. La primera línea es un ejemplo de una de esas variables.

Con la primera línea, puede instanciar container para que sea cualquier clase concreta que implemente IUnityContainer. Con la segunda línea, el objeto container solo se pudo crear una instancia de la clase UnityContainer o una clase derivada.

Cuando utiliza variables de interfaz en su código, le permite cambiar más fácilmente la implementación concreta, lo que hace que su código sea más flexible.

+0

Eso no es realmente cierto. 'UnityContainer' implementa' IUnityContainer', por lo que puede pasar la segunda variable a los métodos que aceptan 'IUnityContainer' también. – dlev

+1

La segunda versión podría usarse con métodos que toman 'IUnityContainer' como su parámetro. Si una clase implementa alguna interfaz, es implícitamente convertible a esa interfaz. – svick

+0

Tienes razón. Lo escribí mal No sé lo que estaba pensando ... – FishBasketGordo

0

El objeto instanciado y almacenado en la variable IUnityContainer container es considerado por el compilador que solo tiene los miembros definidos en la interfaz IUnityContainer. Es decir, si la clase UnityContainer contiene miembros que no están definidos por la interfaz IUnityContainer, no podrá invocarlos. Por otro lado, podría "poner" cualquier objeto que implemente la interfaz IUnityContainer en la variable IUnityContainer container, no solo instancias de UnityContainer. Con la segunda declaración, está atascado con instancias de UnityContainer y objetos en su jerarquía de herencia.

Consulte el C# Programming Guide to Interfaces para obtener más información sobre las interfaces y cómo se usan.

+0

Cuando dijo "propiedades", probablemente quiso decir "miembros". – svick

+0

Actualizado. Gracias, @svick! –

0

La creación de instancias de interfaz no es posible. Pero cuando creamos un objeto para la interfaz usando su clase implementada, funciona.

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

Supongamos que hay una herencia múltiple, para lograr esto tenemos que ir primero.

No hay necesidad de proporcionar tales cosas que vamos con la segunda vía.

Las interfaces restringen el acceso directo de los datos y los miembros de su clase.

Cuestiones relacionadas