2008-11-05 15 views
11

Empecé con una interfaz genérica llamada ILogin. Las interfaces requieren que implemente dos propiedades: ID de usuario y Contraseña. Tengo muchas clases de tipo de inicio de sesión que implementan esta interfaz. A medida que mi proyecto creció y creció, descubrí que muchas clases repetían el código de identificación de usuario y contraseña. Ahora decido que necesito una clase de inicio de sesión.¿Hay alguna ventaja en tener una clase abstracta y una interfaz?

¿Es correcto crear una clase de inicio de sesión abstracta que implemente la interfaz ILogin y que todas mis clases concretas hereden de la clase abstracta y anular cuando sea necesario? Originalmente estaba pensando que no habría ningún problema con esto. Entonces comencé a pensar que ILogin probablemente no era necesario porque probablemente solo sea implementado por mi clase abstracta.

¿Hay algún beneficio en mantener tanto la clase abstracta como la interfaz?

Gracias!

Respuesta

15

Definitivamente. Pensemos en un ejemplo concreto.

Digamos que tenemos una clase abstracta Animal. Digamos, hacemos algunas subclases Cat, Dog, Mosquito y Eagle. Podemos implementar sus métodos Eat(), Breathe(), Sleep() de la clase abstracta Animal.

Hasta ahora, todo bien. Ahora, digamos que queremos tener el método Fly() para las clases Mosquito y Eagle. Dado que estos dos organismos no están realmente bien relacionados (uno es un pájaro, otro es un insecto) no sería fácil encontrar un ancestro común para los dos que podemos tener como clase abstracta. Esto se implementaría mejor mediante una interfaz IFly.

La interfaz IFly puede tener un método Fly() para implementarse. Ambos Mosquito y Eagle clases pueden ser ambas subclases de la clase abstracta Animal e implementan la interfaz IFly y ser capaz de Eat(), Breathe(), Sleep() y Fly() sin tener algún tipo de relación ancenstral extraña entre las dos clases.

1

Si la clase abstracta tiene funcionalidad, es aconsejable guardarla. Pero si solo contiene métodos abstractos y ningún campo. No veo uso para mantener ambos.

Editar: Trabajo en código heredado con muchas clases abstractas. Si alguna vez tengo tiempo, agregaré las interfaces (y posiblemente eliminaré los resúmenes vacíos). Porque trabajar con interfaces mejora enormemente las posibilidades. Y honran su nombre al definir exactamente la interfaz.

4

Normalmente codigo contra clases abstractas cuando tiene sentido e implemento (y creo en un ensamblado/biblioteca de contratos externos) una interfaz en cada clase (abstracta o no) para poder implementar Windows Communication Foundation o inversion of control más fácilmente cuando sea necesario (que casi siempre es para burlarse). Esto se ha convertido en una segunda naturaleza para mí.

+0

+1: No hay absolutos (¡incluso esta afirmación!). –

2

Absolutamente. La interfaz siempre es la forma correcta de hacerlo, de esa manera cualquier cosa puede implementarla (incluso algo que ya tiene un padre).

La clase abstracta tiende a hacerlo para que no tenga que volver a implementar algunos elementos de esa funcionalidad. Swing lo usa un poco, tendrán una interfaz y luego una implementación predeterminada para que anule solo uno de los 5 métodos o puede que se encargue de agregar escuchas para usted, pero no tiene que usar esa clase base si no quiero.

2

Si su clase abstracta es única clase que alguna vez implementará la interfaz, entonces siempre puede verificar las instancias de la clase abstracta, no necesita la interfaz. Pero si quiere ser compatible en el futuro con nuevas clases aún no escritas que no extenderán la clase abstracta, pero podrían usar la interfaz, entonces continúe usando la interfaz ahora.

1

Estoy de acuerdo con cfeduke. SIEMPRE comienzo con interfaces y en el pasado he utilizado clases abstractas que implementan interfaces y proporcionan una funcionalidad básica para promover la reutilización de código entre las clases que heredan de la clase abstracta. En general, la burla y el COI dependen de la interfaz, por este motivo utilizaría interfaces en mis diseños.

0

Siempre le aconsejo que use interfaces. Las clases abstractas tienen la ventaja de que puede agregar funcionalidad predeterminada, pero requerir que un usuario use su herencia individual es bastante agresivo.

Las bibliotecas de clases de Microsoft favorecen las clases abstractas sobre las interfaces en varios casos porque les permite modificar la clase subyacente. Agregar un método a una clase abstracta rara vez rompe a alguien que hereda de él.Agregar un método a una interfaz siempre rompe sus implementadores. Sin embargo, esto proporciona una de las mejores razones para usar interfaces: la horrible posibilidad de que Microsoft ya haya agotado su herencia.

Sugeriría, sin embargo, que en su caso particular, es posible que desee volver a visitar el patrón de diseño que está utilizando. Parece inusual tener muchas clases de "tipo de inicio de sesión".

+0

Todas las clases de inicio de sesión tendrán nombre de usuario y contraseña. Tipos de inicio de sesión más específicos (como sqllogin) extenderán esto y tendrán bases de datos, aproleid, approlepw, trustedconnection, etc. Hay muchos tipos. –

0

Creo que una ventaja de mantener la interfaz sería la posibilidad de que las futuras clases implementen múltiples interfaces mientras que una clase solo puede heredar de una clase abstracta.

Puede ampliar la funcionalidad de las subclases creando una nueva interfaz con un conjunto diferente de métodos.

1

Su interfaz define el contrato que debe cumplirse para que el objeto sea aceptado; su clase abstracta define el contrato que debe cumplirse Y define algunos detalles de implementación específicos.

Piénselo de esta manera; si cree que alguna vez es posible que alguien quiera cumplir ese contrato de una manera diferente a la forma en que la clase abstracta esboza (digamos, con una implementación de tipo de datos de respaldo diferente), entonces debe tener tanto la interfaz como la clase abstracta que implementa eso.

Casi no hay gastos generales involucrados en tener tanto la clase abstracta como la interfaz; su riesgo con ese enfoque implica principalmente que un codificador posterior se encuentre con la interfaz, sin darse cuenta de que hay una clase abstracta que implementa la interfaz y que crea una implementación completa desde cero donde no es necesario. Diría que esto se puede conseguir especificando en la documentación de su interfaz que hay una implementación "predeterminada" de la interfaz en su clase abstracta; mientras que algunos estándares de codificación pueden fruncir el ceño en esa práctica, no veo ningún problema real con ella.

0

Suponiendo que usted está pidiendo específicamente cuando la interfaz y la clase abstracta tienen firmas idénticas ...

...(Si los miembros de la interfaz son diferentes de los miembros de la clase abstracta, por supuesto la respuesta es sí, puede haber una necesidad para ambos)

... pero suponiendo que los miembros son idénticos, entonces La única razón por la que se me ocurre necesitar ambos es que si está codificando en un sistema que no permite la herencia de implementación múltiple, hay dos clases en su sistema que necesitan ser polimórficamente similares, pero deben heredar de diferentes clases base ...

Cuestiones relacionadas