una que programacion polimorfismo orientada objetos multiple interfaz interfaces implementacion herencia classes clase abstracta c# inheritance interface

que - Herencia vs. interfaz en C#



polimorfismo c# (9)

Posibles duplicados:
Interfaz vs clase base
¿Cuándo debo elegir la herencia sobre una interfaz al diseñar bibliotecas de clase C #?

Así que estoy escribiendo mi primer programa real en C #. El programa raspará los datos de cuatro sitios web diferentes. Mi plan es tener una clase para padres que se vea así:

class Scraper { string scrapeDate(url); string scrapeTime(url); //&c. }

Entonces tendré cuatro clases que heredarán de ella.

La otra opción es hacer de Scraper una interfaz y tener cuatro clases implementándola.

¿Cuáles son las diferencias entre estos enfoques?


La herencia de clase representa una relación "is-a", por ejemplo, un Tank es un Vehicle . Si su situación al menos no cumple con esto, elija la interfaz sobre la herencia.

Si la clase base propuesta no proporciona implementaciones predeterminadas para sus métodos, esta sería otra razón para elegir la interfaz sobre la herencia.

En C #, solo puede heredar de una clase pero múltiples interfaces. Esta sería otra razón más para elegir la interfaz sobre la herencia.

¿Captar la idea?


La herencia es, en mi opinión, el mejor enfoque cuando es posible. La implementación de características comunes en una clase base ayuda a garantizar que la implementación subyacente sea consistente, mientras que la implementación de una interfaz solo garantiza que la interfaz sea consistente. La herencia siempre que sea posible es un tramo del trípode OOP y limita la duplicación de códigos.

Utilizo interfaces cuando tengo objetos que no pueden o no deberían tener una clase base común, pero debo proporcionar una funcionalidad similar. Las clases que implementan una interfaz común pueden (y probablemente lo hacen) exponer funcionalidades adicionales, pueden implementar múltiples interfaces, etc.

Por ejemplo: en una aplicación, mi capa de acceso a datos se basa en clases de "proveedor", que aíslan los objetos de negocios y los objetos de proxy de base de datos de la base de datos. En una instancia, tengo un proveedor que interactúa con una base de datos de SQL Server y otro para comunicarse con Oracle CRM On Demand (también conocido como Why God Why). Ambos implementan una interfaz independiente para que al código del cliente no le importe con qué almacén de datos está tratando, o las peculiaridades de trabajar con cada uno.

El proveedor de Oracle se comunica con un servidor alojado a través de una colección de servicios web, administra sesiones de conexión, solicitudes de lotes, etc. El proveedor de SQL utiliza un conjunto de procedimientos almacenados. Aunque ambas interfaces aceptan las mismas clases de datos, el proveedor de Oracle transforma los datos para que coincidan con su esquema esotérico (para ponerlo a la ligera). Con esta implementación, podría agregar fácilmente un proveedor para usar un almacén de datos XML, un RDBMS diferente o una prueba de unidad de código auxiliar / simulacro.

En esta situación, no tiene mucho sentido que estas cosas tengan una clase base común y, en algunos casos, es imposible.


Las interfaces permiten definir la estructura de los comportamientos comunes.

La herencia es útil si puede extraer una implementación común de uno o más comportamientos específicos.

Básicamente, si varias clases eliminan una fecha de la misma manera, tiene sentido colocar scrapeDate en una clase base; de lo contrario, use solo una interfaz y defina la fecha de desecho específica en cada clase que implementa su interfaz.


Lo que pareces tener aquí realmente se sirve mejor como una interfaz. Si tuviera alguna lógica común que deseara incluir o algunos miembros de datos comunes que deseara, entonces usaría una Clase Base y la heredaría de ella. Lo que está haciendo es requerir que cada niño implemente un conjunto mínimo de lógica.


Principales diferencias:

  • una interfaz no tiene ninguna implementación, mientras que una clase base abstracta puede implementar una funcionalidad común
  • una clase solo puede heredar de una clase base, pero puede implementar múltiples interfaces

En su caso, es probable que todas sus clases de raspadores necesiten algunas características comunes, por lo que tiene sentido hacer que todas se hereden de una clase base común


Refiriéndose a la clase abstracta versus interfaz .

Hay algunas similitudes y diferencias entre una interfaz y una clase abstracta:

Una clase puede implementar varias interfaces.
Una clase puede heredar solo una clase abstracta.

Una interfaz no puede proporcionar ningún código, solo la firma.
Una clase abstracta puede proporcionar un código completo, predeterminado y / o solo los detalles que deben anularse.

Una interfaz no puede tener modificadores de acceso para las subs, funciones, propiedades, etc. todo se asume como público
Una clase abstracta puede contener modificadores de acceso para las subs, funciones, propiedades

Las interfaces se utilizan para definir las habilidades periféricas de una clase. En otras palabras, tanto el Humano como el Vehículo pueden heredar de una interfaz IMvable.
Una clase abstracta define la identidad central de una clase y allí se usa para objetos del mismo tipo.

Si varias implementaciones solo comparten firmas de métodos, entonces es mejor usar interfaces.
Si varias implementaciones son del mismo tipo y usan un comportamiento o estado común, es mejor usar la clase abstracta.

Si agregamos un nuevo método a una Interfaz, entonces debemos rastrear todas las implementaciones de la interfaz y definir la implementación para el nuevo método.
Si agregamos un nuevo método a una clase abstracta, tenemos la opción de proporcionar una implementación predeterminada y, por lo tanto, todo el código existente podría funcionar correctamente.

No se pueden definir campos en las interfaces.
Una clase abstracta puede tener campos e interpretantes definidos.


Si tiene una funcionalidad común, debe usar la herencia: la funcionalidad estará disponible en todas las clases secundarias, y cada clase secundaria puede extender o anular el código de clase principal.

Si tiene algo que consume sus clases, usaría interfaces para asegurarse de que todas las clases implementen los mismos métodos y propiedades, pero no necesariamente la misma funcionalidad.


Sinceramente, hacer ambas cosas.

public interface IScraper { string ScrapeDate(string url); } public abstract class Scraper : IScraper { public string ScrapeDate(string url) { // default implementation } }

Hay ventajas de cualquier manera, pero son difíciles de cuantificar sin saber más sobre sus requisitos. Sin embargo, no hay razón para que no puedas hacer ambas cosas. Tener una interfaz para su clase también lo hace simulable para propósitos de prueba.

Algo más para considerar sin embargo; Si la funcionalidad de cada una de sus clases derivadas es lo suficientemente similar, puede ser más fácil simplemente tener una sola clase que lleve los parámetros al constructor.


Una interfaz contiene solo las firmas de métodos, delegados o eventos. La implementación de los métodos se realiza en la clase que implementa la interfaz.

Una clase puede implementar múltiples interfaces.

Una clase solo puede tener una clase base directa.