2010-11-12 38 views
27

No entiendo cómo usar interfaces y por qué son necesarias. ¿Alguien puede mostrarme un ejemplo simple?C# - ¿Alguien puede mostrarme un ejemplo muy simple de interfaces

+8

Enchufe la "interfaz" en el cuadro de búsqueda. Hay algunos excelentes hilos de pregunta/respuesta que ya están en SO. Por ejemplo: http://stackoverflow.com/questions/444245/how-will-i-know-when-to-create-an-interface –

+2

Hay docenas de preguntas sobre interfaces, incluyendo un puñado de "¿qué son y por qué/cómo usarlos "pregunta. Además, Google. (Editar: Ahora -1. No necesariamente votaría negativamente, pero esta pregunta tampoco merece votaciones alternas) – delnan

Respuesta

46
interface IFlyable 
{ 
    void Fly(); 
} 

class Bird : IFlyable 
{ 
    public void Fly() { } 
} 

class Plane : IFlyable 
{ 
    public void Fly() { } 
} 

List<IFlyable> things = GetBirdInstancesAndPlaneInstancesMixed(); 
foreach(IFlyable item in things) 
{ 
    item.Fly(); 
} 

Bird y Plane tienen ninguna clase base común excepto Object, pero se puede ver utilizando la misma interfaz que podemos tratar con ellos grouply en nuestro programa, porque tienen la misma "función": Mosca.

+1

muchas gracias, esto tiene más sentido para mí –

+0

¿Qué diferencia si tiene razón: 'clase IFlyable'? ¿Qué necesidad de interfaz? –

+1

@AmirZojaji Porque 'Plane' probablemente ya tiene una clase base como' Machine', y 'Bird' tiene su clase base' Animal'. Las interfaces son fáciles de combinar, a diferencia de las clases base. –

8

Interfaces son de alguna manera la definición de clase, una especie de contrato entre el interface y la clase que lo implementa.

Una interfaz contiene solo las firmas de métodos, propiedades, eventos o indexadores. Una clase o estructura que implementa la interfaz debe implementar los miembros de la interfaz que se especifican en la definición de la interfaz.

Una clase .NET no puede usar multi-herencia. Como tal, confiamos en las interfaces, y una clase puede implementar tantas interfaces como desee. Por el contrario, una herencia de clase debe ser única. Por ejemplo:

public class Customer : Person, Company { 
} 

Este código no está permitido en cualquier lenguaje .NET, que yo sepa (C#/VB.NET).

Para contrarrestar esta falta, si podemos decirlo, confiamos en las interfaces.

public interface IPerson { 
    string Name 
    string Address 
    string StateProvince 
    string ZipPostalCode 
    string Country 
    long PhoneNumber 
} 

public interface ICompany { 
    string CreditTerm 
    string BillingAddress 
    string ShippingAddress 
    string ContactName 
    long ContactPhoneNumber 
    long FaxNumber 
} 

public class Customer : IPerson, ICompany { 
    // Properties implementations here. 
} 

De esta manera, las interfaces son como una solución de alguna manera a la herencia múltiple.

Por otro lado, las interfaces se pueden utilizar como un contrato de métodos. Supongamos que tiene un método que toma un ICompany como parámetro de entrada. Ahora está seguro de tener las propiedades definidas en la interfaz ICompany para realizar su trabajo dentro del método.

public BillCompany(ICompany company) { 
    // Bill company here... 
} 

Entonces, la clase Customer corresponde a lo que se esperaba, ya que implementa la interfaz ICompany.

Hagamos otra clase, cuya definición solo implementaría la interfaz IPerson.

public class Individual : IPerson { 
    // Interface implementation here... 
} 

Entonces, el método de BillCompany() no podía aceptar una instancia de la clase Individual, ya que no muestra los requisitos (propiedades, etc.) para una empresa.

En resumen, las interfaces son una buena forma de vincular mediante contrato sus métodos a lo que se aceptará, como la herencia.

De hecho, hay algunas precauciones que tomar mientras trabaja con Interface s, un cambio en una interfaz romperá su código, como una regla de aplicación para implementar el nuevo miembro en todas las clases de implementación, que herencia de clase no lo hace.

¿Le sirve de ayuda?

+0

basada en [msdn] (https://msdn.microsoft.com/en-us/library/ms173156. aspx) Una interfaz no puede contener ** constantes **, ** campos **, ** operadores **, ** constructores de instancias **, ** destructores **, o ** tipos **. por favor edite su respuesta – ako

4

Me gusta este blog que leí el otro día: http://simpleprogrammer.com/2010/11/02/back-to-basics-what-is-an-interface/

Mucha gente, incluido yo mismo, han creado interfaces que tienen una correspondencia 1 a 1 a la clase que representan, pero esto no siempre es una buena cosa y ese artículo explica por qué.

+1

¡Buen artículo! Gracias por publicar ese enlace. –

+0

@aaaaaaaaaaaaaaaaa ¿por qué no lo marcaste? –

+0

@girl: Porque no puedo votar. Me niego a ser un usuario registrado. –

0

Bien desde MSDN, "Una interfaz define un contrato.Una clase o estructura que implementa una interfaz debe cumplir con su contrato. "

En this page, hay varios ejemplos de cómo es una interfaz, cómo una clase hereda de una interfaz y un ejemplo completo de cómo implementar una interfaz.

Espero que esto ayude a algunos.

26
public interface ISpeaks 
{ 
    string Speak(); 
} 

public class Dog : Mammal, ISpeaks 
{ 
    public string Speak() { return "Woof!"; } 
} 

public class Person : Mammal, ISpeaks 
{ 
    public string Speak() { return "Hi!"; } 
} 

//Notice Telephone has a different abstract class 
public class Telephone : Appliance, ISpeaks 
{ 
    public Telephone(Person p) 
    { 
     Person = p; 
    } 
    public Person { get; set; } 
    public string Speak() { p.Speak(); } 
} 


[Test] 
public void Test_Objects_Can_Speak() 
{ 
    List<ISpeaks> thingsThatCanSpeak = new List<ISpeaks>(); 
    //We can add anything that implements the interface to the list 
    thingsThatCanSpeak.Add(new Dog()); 
    thingsThatCanSpeak.Add(new Person()); 
    thingsThatCanSpeak.Add(new Telephone(new Person())); 

    foreach(var thing in thingsThatCanSpeak) 
    { 
     //We know at compile time that everything in the collection can speak 
     Console.WriteLine(thing.Speak()); 
    } 
} 

esto es útil porque nos permite código con la interfaz en lugar de la ejecución y porque podemos usar múltiples interfaces en una sola clase, somos más flexibles que si utilizamos una clase abstracta.

+0

Excepto tus 'cosasThatCanSpeak.Add (teléfono nuevo());' no funciona porque el teléfono requiere una persona en el constructor;) – Nate

+0

+1 para mostrar el bit abstracto, las interfaces definen algo que deberían hacer las clases heredadas, no qué clases heredadas deberían ser. –

+0

@Nate Gracias por eso, se agregó más adelante para ilustrar la diferencia de clase abstracta. –

4

Una interfaz es útil cuando tiene un contrato determinado que quiere que un objeto cumpla, pero realmente no le importa cómo lo cumplen. Ese es un detalle de implementación que le queda a la clase.

Digamos que tiene un método cuyo trabajo es procesar las solicitudes de guardado. No realiza el acto real de guardar, solo procesa las solicitudes. Como resultado, puede tomar un List<ICanSave>, donde ICanSave es una interfaz. Los objetos en esa lista pueden ser de cualquier tipo que implemente esa interfaz. Puede ser una mezcla, o puede contener solo un tipo. Simplemente te preocupa que implemente la interfaz.

public interface ICanSave 
{ 
    void Save(); 
} 

En su método, que podría tener algo tan simple como

public void SaveItems(List<ICanSave> items) 
{ 
    foreach (var item in items) 
    { 
     item.Save(); 
    } 
} 

Cómo son aquellos artículos que se guardan? ¡No te importa! Eso, nuevamente, es un detalle de implementación para la clase que implementa la interfaz. Solo quieres que cualquier clase que entre en el método tenga esa habilidad.

Puede tener una clase que implemente la interfaz que conserva los datos en el sistema de archivos. Otro podría guardar en una base de datos. Otro puede llamar a algún servicio externo. Etc. Eso queda para que lo decida el autor de la clase. Incluso puede tener una clase cortada para una prueba unitaria que no hace nada en absoluto.

Es solo un caso de uso, hay muchos otros, varios en el BCL. IEnumerable<T> es bueno, se implementa por cosas como ICollection<T> y IList<T>, que a su vez se implementan por tipos de hormigón como Array y List<T>. Es la interfaz que hace que muchas de las construcciones de programación que pueda estar acostumbrado sean útiles, como LINQ. A LINQ no le importa la implementación real * de la clase, solo quiere poder enumerarla y realizar el filtrado y/o la proyección adecuados.

IDisposable es otro buen ejemplo de BCL. Desea saber que una clase necesita limpiarse por sí misma. Lo que específicamente necesita limpiar queda en manos de la clase, pero por naturaleza de implementar IDisposable, usted sabe que necesita para limpiarlo por sí mismo, por lo que prefiere envolver su uso en una declaración using o asegurarse manualmente de que llama al .Dispose una vez que hayas terminado de trabajar con el objeto.

* LINQ realmente se optimiza para algunas interfaces.

1

"Tengo un montón de clases aquí que quiero tratar de la misma manera, para una cierta cantidad de funcionalidad".

Entonces, usted redacta un contrato.

Ejemplo del mundo real: Estoy escribiendo un asistente. Tiene un montón de páginas, algunas de las cuales (pero no todas) son UserControls. Todos necesitan un conjunto común de operaciones, por lo que la clase controladora puede tratarlos de todos modos. Así que tengo una interfaz IPage que todos ellos implementan, con operaciones como inicializar la página, guardar las elecciones del usuario, etcétera. En mi controlador, simplemente tengo una lista, y no tengo que saber qué página hace qué; Simplemente llamo Save() s de la interfaz e Initialize() s.

3

ejemplo simple de Animal interfaz con dos implementación de animales de clase (que tiene una descripción única para los animales y muchos implementación en la clase de perro, gato ...)

public interface IAnimal 
{ 
    string GetDescription(); 
} 

class Cat : IAnimal 
{  
    public string GetDescription() 
    { 
     return "I'm a cat"; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Cat myCat = new Cat(); 

     Console.WriteLine(myCat.GetDescription()); 
    } 
} 
+0

Incluso puedo entender desde aquí :) –

1

Aquí es los puntos principales de la interfaz,

1. Podemos llamar al mismo método utilizando diferentes clases con diferente salida de los mismos métodos.

ejemplo sencillo:

class Mango : abc 
{ 
    public static void Main() 
    { 
     System.Console.WriteLine("Hello Interfaces"); 
     Mango refDemo = new Mango(); 
     refDemo.mymethod(); 
     Orange refSample = new Orange(); 
     refSample.mymethod(); 

    } 

    public void mymethod() 
    { 
     System.Console.WriteLine("In Mango : mymethod"); 
    } 
} 

interface abc 
{ 
    void mymethod(); 
} 

class Orange : abc 
{ 
    public void mymethod() 
    { 
     System.Console.WriteLine("In Orange : mymethod"); 
    } 
} 

2.Can llamada mismo método usando misma interfaz con diferentes clases.

class Mango : abc 
{ 
    public static void Main() 
    { 
     System.Console.WriteLine("Hello Interfaces"); 
     abc refabc = new Mango(); 
     refabc.mymethod(); 
     abc refabd = new Orange(); 
     refabd.mymethod(); 
     Console.ReadLine(); 
    } 

    public void mymethod() 
    { 
     System.Console.WriteLine("In Mango : mymethod"); 
    } 
} 

interface abc 
{ 
    void mymethod(); 
} 

class Orange : abc 
{ 
    public void mymethod() 
    { 
     System.Console.WriteLine("In Orange : mymethod"); 
    } 
} 
+0

¿Puedes ver la diferencia entre dos ejemplos? –

Cuestiones relacionadas