what programming oriented oop interface

oop - programming - ¿Por qué no puedo entender las interfaces?



packages in object oriented programming (26)

Además de la función que tienen las interfaces dentro de los lenguajes de programación, también son una poderosa herramienta semántica al expresar ideas de diseño a otras personas .

Una base de código con interfaces bien diseñadas es de repente mucho más fácil de discutir. "Sí, necesita un CredentialsManager para registrar nuevos servidores remotos". "Pase un PropertyMap a ThingFactory para obtener una instancia de trabajo".

La capacidad de abordar una cosa compleja con una sola palabra es bastante útil.

¿Podría alguien desmitificar las interfaces para mí o señalarme algunos buenos ejemplos? Sigo viendo interfaces emergentes aquí y allá, pero nunca he estado expuesto a buenas explicaciones de las interfaces o cuándo usarlas.

Estoy hablando de interfaces en un contexto de interfaces vs. clases abstractas.


Aquí hay un ejemplo relacionado con DB que uso a menudo. Digamos que tiene un objeto y un objeto contenedor como una lista. Supongamos que alguna vez quiera almacenar los objetos en una secuencia particular. Supongamos que la secuencia no está relacionada con la posición en la matriz, sino que los objetos son un subconjunto de un conjunto más grande de objetos y la posición de la secuencia está relacionada con el filtrado sql de la base de datos.

Para realizar un seguimiento de las posiciones de secuencia personalizadas, puede hacer que su objeto implemente una interfaz personalizada. La interfaz personalizada podría mediar el esfuerzo organizacional requerido para mantener tales secuencias.

Por ejemplo, la secuencia que le interesa no tiene nada que ver con las claves primarias en los registros. Con el objeto que implementa la interfaz, puede decir myObject.next () o myObject.prev ().


Como otros han dicho aquí, las interfaces definen un contrato (cómo se verán las clases que usan la interfaz) y las clases abstractas definen la funcionalidad compartida.

Veamos si el código ayuda:

public interface IReport { void RenderReport(); // this just defines the method prototype } public abstract class Reporter { protected void DoSomething() { // this method is the same for every class that inherits from this class } } public class ReportViolators : Reporter, IReport { public void RenderReport() { // some kind of implementation specific to this class } } public class ClientApp { var violatorsReport = new ReportViolators(); // the interface method violatorsReport.RenderReport(); // the abstract class method violatorsReport.DoSomething(); }


Cuando manejas el automóvil de un amigo, más o menos sabes cómo hacerlo. Esto se debe a que los autos convencionales tienen una interfaz muy similar: volante, pedales, etc. Piense en esta interfaz como un contrato entre los fabricantes de automóviles y los conductores. Como conductor (el usuario / cliente de la interfaz en términos de software), no necesita aprender los detalles de los diferentes automóviles para poder conducirlos: por ejemplo, todo lo que necesita saber es que al girar el volante se coche a su vez. Como fabricante de automóviles (el proveedor de una implementación de la interfaz en términos de software) tiene una idea clara de lo que debe tener su nuevo automóvil y cómo debe comportarse para que los conductores puedan usarlos sin mucha capacitación adicional. Este contrato es lo que las personas en el diseño de software llaman desacoplamiento (el usuario del proveedor): el código del cliente es en términos de usar una interfaz en lugar de una implementación particular de la misma y por lo tanto no necesita conocer los detalles de los objetos implementando la interfaz.


En pocas palabras: una interfaz es una clase que los métodos definen, pero no la implementación en ellos. En contraste, una clase abstracta tiene algunos de los métodos implementados, pero no todos.


Este es un tema bastante "largo", pero permítanme intentar ponerlo simple.

Una interfaz es -como "lo nombran" - un Contrato. Pero olvídate de esa palabra.

La mejor forma de entenderlos es a través de algún tipo de ejemplo de pseudocódigo. Así es como los entendí hace mucho tiempo.

Supongamos que tiene una aplicación que procesa mensajes. Un mensaje contiene algunas cosas, como un tema, un texto, etc.

Entonces, escribe su MessageController para leer una base de datos y extraer mensajes. Es muy lindo hasta que de repente escuchas que los faxes también se implementarán pronto. ¡Entonces tendrá que leer "Faxes" y procesarlos como mensajes!

Esto podría convertirse fácilmente en un código de Spagetti. Entonces, lo que haces en lugar de tener un MessageController que solo controla los "Mensajes", lo haces capaz de trabajar con una interfaz llamada IMessage (el I es solo un uso común, pero no obligatorio).

Su interfaz de IMessage contiene algunos datos básicos que necesita para asegurarse de que puede procesar el mensaje como tal.

Entonces, cuando crea sus clases de Correo Electrónico, Fax, Llamada Telefónica, hace que Implemente la Interfaz llamada IMessage .

Entonces en su MessageController, puede tener un método llamado así:

private void ProcessMessage(IMessage oneMessage) { DoSomething(); }

Si no hubiera utilizado interfaces, tendría que tener:

private void ProcessEmail(Email someEmail); private void ProcessFax(Fax someFax); etc.

Por lo tanto, al usar una interfaz común , se aseguró de que el método ProcessMessage pueda funcionar con ella, sin importar si se trata de un fax, un correo electrónico, una llamada telefónica, etc.

¿Por qué o cómo ?

Porque la interfaz es un contrato que especifica algunas cosas que debe cumplir (o implementar) para poder usarlo. Piense en ello como una insignia . Si su objeto "Fax" no tiene la interfaz IMessage, entonces su método ProcessMessage no podría funcionar con eso, le dará un tipo no válido, porque está pasando un fax a un método que espera un mensaje IMessage objeto.

¿Ves el punto?

Piense en la interfaz como un "subconjunto" de métodos y propiedades que tendrá disponibles, a pesar del tipo de objeto real. Si el objeto original (fax, correo electrónico, llamada telefónica, etc.) implementa esa interfaz, puede pasarla de manera segura a través de los métodos que necesitan esa interfaz.

Hay más magia escondida allí, puedes CASTAR las interfaces a sus objetos originales:

Fax myFax = (Fax) SomeIMessageThatIReceive;

ArrayList () en .NET 1.1 tenía una bonita interfaz llamada IList. Si tuviera un IList (muy "genérico") podría transformarlo en ArrayList:

ArrayList ar = (ArrayList)SomeIList;

Y hay miles de muestras en la naturaleza.

Las interfaces como ISortable, IComparable, etc., definen los métodos y las propiedades que debe implementar en su clase para lograr esa funcionalidad.

Para expandir nuestra muestra, podría tener una Lista <> de Correos electrónicos, Fax, Llamada telefónica, todos en la misma Lista, si el Tipo es IMessage, pero no podría tenerlos todos juntos si los objetos fueran simplemente Correo electrónico, Fax, etc. .

Si quisiera clasificar (o enumerar, por ejemplo) sus objetos, los necesitaría para implementar la interfaz correspondiente. En el ejemplo de .NET, si tiene una lista de objetos de "Fax" y desea poder ordenarlos utilizando MyList.Sort (), debe hacer que su clase de fax sea la siguiente:

public class Fax : ISorteable { //implement the ISorteable stuff here. }

Espero que esto te dé una pista. Otros usuarios posiblemente publicarán otros buenos ejemplos. ¡Buena suerte! y Abrazar el poder de las interfaces.

advertencia : no todo es bueno acerca de las interfaces, hay algunos problemas con ellas, los puristas de OOP comenzarán una guerra en esto. Me mantendré a un lado. Un inconveniente de una Interfcie (en .NET 2.0 al menos) es que no puede tener miembros PRIVADOS, o protegidos, debe ser público. Esto tiene sentido, pero a veces desearía simplemente declarar cosas como privadas o protegidas.


Java no permite la herencia múltiple (por muy buenas razones, busque el diamante terrible), pero ¿qué sucede si desea que su clase suministre varios conjuntos de comportamiento? Digamos que quiere que cualquiera que lo use sepa que puede ser serializado, y también que puede pintarse en la pantalla. la respuesta es implementar dos interfaces diferentes.

Debido a que las interfaces no contienen implementación de sus propios miembros y no hay miembros de instancia, es seguro implementar varios de ellos en la misma clase sin ambigüedades.

El inconveniente es que tendrá que tener la implementación en cada clase por separado. Entonces, si su jerarquía es simple y hay partes de la implementación que deberían ser iguales para todas las clases heredadas, use una clase abstracta.


La respuesta más fácil es que las interfaces definen lo que tu clase puede hacer. Es un "contrato" que dice que su clase podrá hacer esa acción.

Public Interface IRollOver Sub RollOver() End Interface Public Class Dog Implements IRollOver Public Sub RollOver() Implements IRollOver.RollOver Console.WriteLine("Rolling Over!") End Sub End Class Public Sub Main() Dim d as New Dog() Dim ro as IRollOver = TryCast(d, IRollOver) If ro isNot Nothing Then ro.RollOver() End If End Sub

Básicamente, estás garantizando que la clase Dog siempre tenga la capacidad de renovarse mientras continúe implementando esa interfaz. Si los gatos alguna vez obtienen la habilidad de RollOver (), también podrían implementar esa interfaz, y puedes tratar tanto a perros como a gatos de forma homogénea cuando les pidas RollOver ().


Las interfaces establecen un contrato entre una clase y el código que lo llama. También le permiten tener clases similares que implementan la misma interfaz pero que realizan diferentes acciones o eventos y no tienen que saber con qué está trabajando en realidad. Esto podría tener más sentido como ejemplo, así que permítanme probar uno aquí.

Supongamos que tiene un par de clases llamadas Perro, Gato y Ratón. Cada una de estas clases es Pet y, en teoría, puedes heredarlas todas de otra clase llamada Pet, pero este es el problema. Las mascotas en sí mismas no hacen nada. No puedes ir a la tienda y comprar una mascota. Puedes ir y comprar un perro o un gato, pero una mascota es un concepto abstracto y no concreto.

Entonces, sabes que las mascotas pueden hacer ciertas cosas. Pueden dormir, comer, etc. Así que defines una interfaz llamada IPet y se ve así (sintaxis C #)

public interface IPet { void Eat(object food); void Sleep(int duration); }

Cada una de sus clases de Perro, Gato y Ratón implementa IPet.

public class Dog : IPet

Entonces, cada una de esas clases debe tener su propia implementación de Eat and Sleep. Sí, tienes un contrato ... Ahora, ¿qué sentido tiene?

A continuación, digamos que desea crear un nuevo objeto llamado PetStore. Y esta no es una PetStore muy buena, así que básicamente te venden una mascota al azar (sí, sé que es un ejemplo inventado).

public class PetStore { public static IPet GetRandomPet() { //Code to return a random Dog, Cat, or Mouse } } IPet myNewRandomPet = PetStore.GetRandomPet(); myNewRandomPet.Sleep(10);

El problema es que no sabes qué tipo de mascota será. Gracias a la interfaz, aunque sabes lo que sea, comerá y dormirá.

Así que esta respuesta puede no haber sido útil en absoluto, pero la idea general es que las interfaces te permiten hacer cosas claras como Dependency Injection e Inversion of Control donde puedes obtener un objeto, tener una lista bien definida de cosas que el objeto puede hacer sin REALMENTE saber cuál es el tipo concreto de ese objeto.


Las interfaces le permiten codificar contra objetos de forma genérica. Por ejemplo, supongamos que tiene un método que envía informes. Ahora diga que tiene un nuevo requisito que entra donde necesita escribir un nuevo informe. Sería bueno si pudieras reutilizar el método que ya habías escrito ¿verdad? Interfaces lo hace fácil:

interface IReport { string RenderReport(); } class MyNewReport : IReport { public string RenderReport() { return "Hello World Report!"; } } class AnotherReport : IReport { public string RenderReport() { return "Another Report!"; } } //This class can process any report that implements IReport! class ReportEmailer() { public void EmailReport(IReport report) { Email(report.RenderReport()); } } class MyApp() { void Main() { //create specific "MyNewReport" report using interface IReport newReport = new MyNewReport(); //create specific "AnotherReport" report using interface IReport anotherReport = new AnotherReport(); ReportEmailer reportEmailer = new ReportEmailer(); //emailer expects interface reportEmailer.EmailReport(newReport); reportEmailer.EmailReport(anotherReport); } }


Las interfaces le permiten programar contra una "descripción" en lugar de un tipo, lo que le permite asociar de manera más vaga elementos de su software.

Piénselo de esta manera: desea compartir datos con alguien en el cubo contiguo a usted, de modo que extraiga su dispositivo flash y copie / pegue. Caminas al lado y el tipo dice "¿es ese USB?" y dices que sí, todo listo. No importa el tamaño de la memoria flash, ni el fabricante, lo único que importa es que es USB.

De la misma manera, las interfaces le permiten generar su desarrollo. Utilizando otra analogía: imagine que quería crear una aplicación que virtualmente pintara autos. Puede tener una firma como esta:

public void Paint(Car car, System.Drawing.Color color)...

Esto funcionaría hasta que su cliente dijera "ahora quiero pintar camiones" para que pueda hacer esto:

public void Paint (Vehicle vehicle, System.Drawing.Color color)...

esto ampliaría tu aplicación ... hasta que tu cliente dijera "¡ahora quiero pintar casas!" Lo que podrías haber hecho desde el principio es crear una interfaz:

public interface IPaintable{ void Paint(System.Drawing.Color color); }

... y se lo pasó a tu rutina:

public void Paint(IPaintable item, System.Drawing.Color color){ item.Paint(color); }

Afortunadamente, esto tiene sentido, es una explicación bastante simplista, pero con suerte llega al meollo del asunto.


Las interfaces son un mecanismo para reducir el acoplamiento entre diferentes partes posiblemente dispares de un sistema.

Desde una perspectiva .NET

  • La definición de interfaz es una lista de operaciones y / o propiedades.
  • Los métodos de interfaz son siempre públicos.
  • La interfaz en sí no tiene que ser pública.

Cuando crea una clase que implementa la interfaz, debe proporcionar una implementación explícita o implícita de todos los métodos y propiedades definidos por la interfaz.

Además, .net solo tiene una herencia única, y las interfaces son una necesidad para que un objeto exponga los métodos a otros objetos que no conocen o que se encuentran fuera de su jerarquía de clases. Esto también se conoce como comportamientos de exposición.

Un ejemplo que es un poco más concreto:

Considere que tenemos muchos DTO (objetos de transferencia de datos) que tienen propiedades para quién se actualizó por última vez, y cuándo fue eso. El problema es que no todos los DTO tienen esta propiedad porque no siempre es relevante. Al mismo tiempo, deseamos un mecanismo genérico para garantizar que estas propiedades se establezcan si están disponibles cuando se envían al flujo de trabajo, pero el objeto del flujo de trabajo debe acoplarse libremente a partir de los objetos enviados. es decir, el método de flujo de trabajo de envío no debería conocer todas las sutilezas de cada objeto, y todos los objetos en el flujo de trabajo no son necesariamente objetos DTO.

// first pass - not maintainable void SubmitToWorkflow(object o, User u) { if( o is StreetMap ) { var map = (StreetMap)o; map.LastUpdated = DateTime.UtcNow; map.UpdatedByUser = u.UserID; } else if( o is Person ) { var person = (Person)o; person.LastUpdated = DateTime.Now; // whoops .. should be UtcNow person.UpdatedByUser = u.UserID; } // whoa - very unmaintainable.

En el código anterior, SubmitToWorkflow() debe conocer todos y cada uno de los objetos. Además, el código es un desastre con un interruptor masivo if / else /, viola el principio de No repetir (DRY) y requiere que los desarrolladores recuerden los cambios de copiar / pegar cada vez que se agrega un nuevo objeto al sistema.

// second pass - brittle void SubmitToWorkflow(object o, User u) { if( o is DTOBase ) { DTOBase dto = (DTOBase)o; dto.LastUpdated = DateTime.UtcNow; dto.UpdatedByUser = u.UserID; }

Un poco mejor, pero aún frágil. Si queremos enviar otros tipos de objetos, aún necesitamos más declaraciones de casos. etc.

// third pass pass - also brittle void SubmitToWorkflow(DTOBase dto, User u) { dto.LastUpdated = DateTime.UtcNow; dto.UpdatedByUser = u.UserID;

Sigue siendo frágil, y ambos métodos imponen la restricción que todos los DTO tienen para implementar esta propiedad que indicamos que no era universalmente aplicable. Algunos desarrolladores podrían sentirse tentados a escribir métodos de "no hacer nada", pero huele mal. No queremos que las clases finjan que admiten el seguimiento de actualizaciones, pero no lo hacen.

Interfaces, ¿cómo pueden ayudar?

Si definimos una interfaz muy simple:

public interface IUpdateTracked { DateTime LastUpdated { get; set; } int UpdatedByUser { get; set; } }

Cualquier clase que necesite este seguimiento automático de actualizaciones puede implementar la interfaz.

public class SomeDTO : IUpdateTracked { // IUpdateTracked implementation as well as other methods for SomeDTO }

El método de flujo de trabajo puede ser mucho más genérico, más pequeño y más fácil de mantener, y continuará funcionando sin importar cuántas clases implementen la interfaz (DTO o de otro tipo) porque solo trata con la interfaz.

void SubmitToWorkflow(object o, User u) { IUpdateTracked updateTracked = o as IUpdateTracked; if( updateTracked != null ) { updateTracked.LastUpdated = DateTime.UtcNow; updateTracked.UpdatedByUser = u.UserID; } // ...

  • Podemos observar la variación void SubmitToWorkflow(IUpdateTracked updateTracked, User u) garantizaría la seguridad del tipo, sin embargo, no parece ser relevante en estas circunstancias.

En algunos códigos de producción que utilizamos, tenemos generación de código para crear estas clases de DTO a partir de la definición de la base de datos. Lo único que hace el desarrollador es crear el nombre del campo correctamente y decorar la clase con la interfaz. Siempre que las propiedades se llamen LastUpdated y UpdatedByUser, simplemente funciona.

Quizás estés preguntando ¿Qué sucede si mi base de datos es heredada y eso no es posible? Solo tienes que escribir un poco más; Otra gran característica de las interfaces es que pueden permitirle crear un puente entre las clases.

En el siguiente código, tenemos un LegacyDTO ficticio, un objeto preexistente que tiene campos con nombres similares. Está implementando la interfaz IUpdateTracked para unir las propiedades existentes, pero con nombres diferentes.

// using an interface to bridge properties public class LegacyDTO : IUpdateTracked { public int LegacyUserID { get; set; } public DateTime LastSaved { get; set; } public int UpdatedByUser { get { return LegacyUserID; } set { LegacyUserID = value; } } public DateTime LastUpdated { get { return LastSaved; } set { LastSaved = value; } } }

Puede ser genial, pero ¿no es confuso tener múltiples propiedades? o ¿Qué sucede si ya existen esas propiedades pero significan algo más? .net le brinda la capacidad de implementar explícitamente la interfaz. Lo que esto significa es que las propiedades de IUpdateTracked solo estarán visibles cuando usemos una referencia a IUpdateTracked. Tenga en cuenta que no hay ningún modificador público en la declaración, y la declaración incluye el nombre de la interfaz.

// explicit implementation of an interface public class YetAnotherObject : IUpdatable { int IUpdatable.UpdatedByUser { ... } DateTime IUpdatable.LastUpdated { ... }

Tener tanta flexibilidad para definir cómo la clase implementa la interfaz le da al desarrollador mucha libertad para desacoplar el objeto de los métodos que lo consumen. Las interfaces son una excelente manera de romper el acoplamiento.

Hay muchas más interfaces que solo esto. Este es solo un ejemplo simplificado de la vida real que utiliza un aspecto de la programación basada en interfaz.

Como mencioné anteriormente, y por otros respondedores, puede crear métodos que toman y / o devuelven referencias de interfaz en lugar de una referencia de clase específica. Si necesitaba encontrar duplicados en una lista, podría escribir un método que tome y devuelva un IList (una interfaz que define operaciones que funcionan en listas) y no estoy limitado a una clase de colección concreta.

// decouples the caller and the code as both // operate only on IList, and are free to swap // out the concrete collection. public IList<T> FindDuplicates( IList<T> list ) { var duplicates = new List<T>() // TODO - write some code to detect duplicate items return duplicates; }

Versioning caveat

Si se trata de una interfaz pública, ¡estás declarando que garantizo que la interfaz x se parece a esto! y una vez que haya enviado el código y publicado la interfaz, nunca debería cambiarlo. Tan pronto como el código del consumidor comienza a confiar en esa interfaz, no desea romper su código en el campo.

Vea esta publicación Haacked para una buena discusión.

Interfaces versus clases abstractas (base)

Las clases abstractas pueden proporcionar implementación mientras que las interfaces no pueden. Las clases abstractas son, en cierto modo, más flexibles en el aspecto de versión si sigue algunas pautas, como el patrón NVPI (interfaz pública no virtual).

Vale la pena reiterar que en .net, una clase solo puede heredar de una sola clase, pero una clase puede implementar tantas interfaces como quiera.

Inyección de dependencia

El resumen rápido de interfaces y DI es que el uso de interfaces permite a los desarrolladores escribir código que se programa en una interfaz para proporcionar servicios. En la práctica, puede terminar con muchas interfaces pequeñas y clases pequeñas, y una idea es que las clases pequeñas que hacen una cosa y una sola cosa son mucho más fáciles de codificar y mantener.

class AnnualRaiseAdjuster : ISalaryAdjuster { AnnualRaiseAdjuster(IPayGradeDetermination payGradeDetermination) { ... } void AdjustSalary(Staff s) { var payGrade = payGradeDetermination.Determine(s); s.Salary = s.Salary * 1.01 + payGrade.Bonus; } }

En resumen, el beneficio que se muestra en el fragmento de arriba es que la determinación de la calificación salarial se acaba de inyectar en el ajustador de aumento anual. Cómo se determina la calificación de pago en realidad no es importante para esta clase. Al realizar pruebas, el desarrollador puede simular los resultados de la determinación del grado de pago para garantizar que el ajustador de sueldos funcione como se desee. Las pruebas también son rápidas porque la prueba solo está probando la clase, y no todo lo demás.

Esto no es un manual de DI, ya que hay libros enteros dedicados al tema; el ejemplo anterior es muy simplificado.


Las interfaces son una forma de exigir que un objeto implemente una cierta cantidad de funcionalidad, sin tener que usar herencia (lo que conduce a un código fuertemente acoplado, en lugar de un acoplamiento débil que puede lograrse mediante el uso de interfaces).

Las interfaces describen la funcionalidad, no la implementación.


Las interfaces son una forma de implementar convenciones de una manera que todavía está fuertemente tipada y polimórfica.

Un buen ejemplo del mundo real sería IDisposable en .NET. Una clase que implementa la interfaz IDisposable obliga a esa clase a implementar el método Dispose (). Si la clase no implementa Dispose () obtendrá un error de compilación al intentar compilar. Además, este patrón de código:

using (DisposableClass myClass = new DisposableClass()) { // code goes here }

Hará que myClass.Dispose () se ejecute automáticamente cuando la ejecución salga del bloque interno.

Sin embargo, y esto es importante, no se aplicará lo que su método Dispose () debería hacer. Puede hacer que su método Dispose () elija recetas aleatorias de un archivo y las envíe por correo electrónico a una lista de distribución, al compilador no le importa. La intención del patrón IDisposable es facilitar los recursos de limpieza. Si las instancias de una clase se aferran a identificadores de archivos, IDisposable hace que sea muy fácil centralizar el desasignamiento y el código de limpieza en un solo lugar y promover un estilo de uso que asegure que siempre se produzca la desasignación.

Y esa es la clave de las interfaces. Son una forma de agilizar las convenciones de programación y los patrones de diseño. Lo cual, cuando se usa correctamente, promueve un código más sencillo de auto-documentación que es más fácil de usar, más fácil de mantener y más correcto.


Las interfaces también son clave para el polimorfismo, uno de los "TRES PILARES DE OOD".

Algunas personas lo mencionaron anteriormente, el polimorfismo simplemente significa que una clase determinada puede asumir diferentes "formas". Es decir, si tenemos dos clases, "Perro" y "Gato" y ambas implementan la interfaz "INeedFreshFoodAndWater" (jeje), tu código puede hacer algo como esto (pseudocódigo):

INeedFreshFoodAndWater[] array = new INeedFreshFoodAndWater[]; array.Add(new Dog()); array.Add(new Cat()); foreach(INeedFreshFoodAndWater item in array) { item.Feed(); item.Water(); }

Esto es poderoso porque le permite tratar diferentes clases de objetos de forma abstracta, y le permite hacer cosas como hacer que sus objetos se acoplen más libremente, etc.


OK, entonces se trata de clases abstractas vs. interfaces ...

Conceptualmente, las clases abstractas están ahí para ser usadas como clases base. Muy a menudo ellos mismos ya proporcionan algunas funcionalidades básicas, y las subclases tienen que proporcionar su propia implementación de los métodos abstractos (esos son los métodos que no se implementan en la clase base abstracta).

Las interfaces se utilizan principalmente para desacoplar el código del cliente de los detalles de una implementación en particular. Además, a veces la capacidad de cambiar la implementación sin cambiar el código del cliente hace que el código del cliente sea más genérico.

En el nivel técnico, es más difícil trazar la línea entre las clases abstractas y las interfaces, porque en algunos idiomas (por ejemplo, C ++), no hay diferencia sintáctica, o porque también se pueden usar clases abstractas para el desacoplamiento o la generalización. Usar una clase abstracta como interfaz es posible porque cada clase base, por definición, define una interfaz que todas sus subclases deberían respetar (es decir, debería ser posible usar una subclase en lugar de una clase base).


Piensa en una interfaz como un contrato. Cuando una clase implementa una interfaz, básicamente está aceptando cumplir los términos de ese contrato. Como consumidor, solo le importa que los objetos que tiene puedan cumplir con sus obligaciones contractuales. Su funcionamiento interno y detalles no son importantes.


Respuesta simple: una interfaz es un conjunto de firmas de métodos (+ tipo de retorno). Cuando un objeto dice que implementa una interfaz, sabes que expone ese conjunto de métodos.


Suponiendo que se refiere a interfaces en lenguajes orientados a objetos de tipo estático, el uso principal es afirmar que su clase sigue un contrato o protocolo particular.

Digamos que tienes:

public interface ICommand { void Execute(); } public class PrintSomething : ICommand { OutputStream Stream { get; set; } String Content {get; set;} void Execute() { Stream.Write(content); } }

Ahora tiene una estructura de comando sustituible. Cualquier instancia de una clase que implemente IExecute se puede almacenar en una lista de algún tipo, digamos algo que implemente IEnumerable y puede recorrerlo y ejecutar cada uno, sabiendo que cada objeto solo hará lo correcto. Puede crear un comando compuesto implementando CompositeCommand que tendrá su propia lista de comandos para ejecutar, o un LoopingCommand para ejecutar un conjunto de comandos repetidamente, luego tendrá la mayoría de un intérprete simple.

Cuando puede reducir un conjunto de objetos a un comportamiento que todos tienen en común, es posible que tenga motivos para extraer una interfaz. Además, a veces puede usar interfaces para evitar que objetos se entrometan accidentalmente en las preocupaciones de esa clase; por ejemplo, puede implementar una interfaz que solo permita a los clientes recuperar, en lugar de cambiar datos en su objeto, y que la mayoría de los objetos reciban solo una referencia a la interfaz de recuperación.

Las interfaces funcionan mejor cuando sus interfaces son relativamente simples y hacen pocas suposiciones.

Busque el principio de sustitución de Liskov para tener más sentido de esto.

Algunos lenguajes de tipo estático como C ++ no admiten interfaces como un concepto de primera clase, por lo que puede crear interfaces utilizando clases abstractas puras.

Actualización Dado que parece que estás preguntando sobre las clases abstractas frente a las interfaces, esta es mi simplificación excesiva preferida:

  • Las interfaces definen capacidades y características.
  • Las clases abstractas definen la funcionalidad central.

Normalmente, hago una refactorización de interfaz de extracto antes de construir una clase abstracta. Es más probable que construya una clase abstracta si creo que debería haber un contrato creacional (específicamente, que un tipo específico de constructor siempre debe ser respaldado por subclases). Sin embargo, raramente uso clases abstractas "puras" en C # / java. Es mucho más probable que implemente una clase con al menos un método que contenga un comportamiento significativo, y utilice métodos abstractos para admitir los métodos de plantilla llamados por ese método. Entonces, la clase abstracta es una implementación básica de un comportamiento, que todas las subclases concretas pueden aprovechar sin tener que volver a implementarla.


Una buena razón para usar una interfaz frente a una clase abstracta en Java es que una subclase no puede extender múltiples clases base, pero PUEDE implementar múltiples interfaces.


I have had the same problem as you and I find the "contract" explanation a bit confusing.

If you specify that a method takes an IEnumerable interface as an in-parameter you could say that this is a contract specifying that the parameter must be of a type that inherits from the IEnumerable interface and hence supports all methods specified in the IEnumerable interface. The same would be true though if we used an abstract class or a normal class. Any object that inherits from those classes would be ok to pass in as a parameter. You would in any case be able to say that the inherited object supports all public methods in the base class whether the base class is a normal class, an abstract class or an interface.

An abstract class with all abstract methods is basically the same as an interface so you could say an interface is simply a class without implemented methods. You could actually drop interfaces from the language and just use abstract class with only abstract methods instead. I think the reason we separate them is for semantic reasons but for coding reasons I don''t see the reason and find it just confusing.

Another suggestion could be to rename the interface to interface class as the interface is just another variation of a class.

In certain languages there are subtle differences that allows a class to inherit only 1 class but multiple interfaces while in others you could have many of both, but that is another issue and not directly related I think


Interface is like a fully abstract class. That is, an abstract class with only abstract members. You can also implement multiple interfaces, it''s like inheriting from multiple fully abstract classes. Anyway.. this explanation only helps if you understand what an abstract class is.


Interfaces require any class that implements them to contain the methods defined in the interface.

The purpose is so that, without having to see the code in a class, you can know if it can be used for a certain task. For example, the Integer class in Java implements the comparable interface, so, if you only saw the method header (public class String implements Comparable), you would know that it contains a compareTo() method.


Most of the interfaces you come across are a collection of method and property signatures. Any one who implements an interface must provide definitions to what ever is in the interface.


Moved to this question after this question was closed as a duplicate, in hope that it will help someone:

In your simple case, you could achieve something similar to what you get with interfaces by using a common base class that implements show() (or perhaps defines it as abstract). Let me change your generic names to something more concrete, Eagle and Hawk instead of MyClass1 and MyClass2 . In that case you could write code like

Bird bird = GetMeAnInstanceOfABird(someCriteriaForSelectingASpecificKindOfBird); bird.Fly(Direction.South, Speed.CruisingSpeed);

That lets you write code that can handle anything that is a Bird . You could then write code that causes the Bird to do it''s thing (fly, eat, lay eggs, and so forth) that acts on an instance it treats as a Bird . That code would work whether Bird is really an Eagle , Hawk , or anything else that derives from Bird .

That paradigm starts to get messy, though, when you don''t have a true is a relationship. Say you want to write code that flies things around in the sky. If you write that code to accept a Bird base class, it suddenly becomes hard to evolve that code to work on a JumboJet instance, because while a Bird and a JumboJet can certainly both fly, a JumboJet is most certainly not a Bird .

Enter the interface.

What Bird (and Eagle , and Hawk ) do have in common is that they can all fly. If you write the above code instead to act on an interface, IFly , that code can be applied to anything that provides an implementation to that interface.


The simplest way to understand interfaces is to start by considering what class inheritance means. It includes two aspects:

  1. Members of a derived class can use public or protected members of a base class as their own.
  2. Members of a derived class can be used by code which expects a member of the base class (meaning they are substitutable).

Both of these features are useful, but because it is difficult to allow a class to use members of more than one class as its own, many languages and frameworks only allow classes to inherit from a single base class. On the other hand, there is no particular difficulty with having a class be substitutable for multiple other unrelated things.

Further, because the first benefit of inheritance can be largely achieved via encapsulation, the relative benefit from allowing multiple-inheritance of the first type is somewhat limited. On the other hand, being able to substitute an object for multiple unrelated types of things is a useful ability which cannot be readily achieved without language support.

Interfaces provide a means by which a language/framework can allow programs to benefit from the second aspect of inheritance for multiple base types, without requiring it to also provide the first.