2010-03-03 18 views
5

Estoy implementando un conjunto de clases e interfaces correspondientes en las que quiero que cada clase tenga un conjunto de propiedades comunes y un conjunto de propiedades especializadas que son específicas solo para esa clase. Por lo tanto, estoy considerando la definición de las interfaces a lo largo de las líneas de:Herencia de Interfaz Múltiple

interface ICommon {...} // Members common to all widgets 
interface IWidget1 {...} // specialized members of widget type 1 
interface IWidget2 {...} // specialized members of widget type 2 

estoy tratando de elegir entre tener la herencia en las interfaces, o en la clase. Así, en concreto, ya sea que puedo hacerlo de esta manera:

interface IWidget1 : ICommon {...} 
interface IWidget2 : ICommon {...} 
class Widget1 : IWidget1 {...} 
class Widget2 : IWidget2 {...} 

... o así ...

class Widget1: ICommon, IWidget1 {...} 
class Widget2: ICommon, IWidget2 {...} 

¿Hay alguna razón de peso para ir en una dirección o la otra?

Actualización: ¿Afectaría la respuesta si las clases deben ser COM-visibles?

Respuesta

6

Debe elegir la herencia de la interfaz si y solo si un tipo que implementa IWidget1 debe también implementar ICommon. En cualquier caso, la clase implementará IWidget1 e ICommon por separado. La única diferencia es que si haces que IWidget1 "se derive" de ICommon, haces cumplir que un IWidget1 también debe ser un ICommon.

Un buen ejemplo es IEnumerable e ICollection. Se garantiza que cada ICollection es IEnumerable, por lo que ICollection se deriva de IEnumerable. Si era legal o tenía sentido ser una colección pero no enumerable, los implementadores de ICollection no tendrían que implementar IEnumerable también.

Cualquiera que elija no afectará la visibilidad de COM. .NET aún exportará las interfaces por separado si no recuerdo mal.

+0

Correcto, sí. Todos los tipos de widgets DEBEN implementar ICommon. Esa es la razón para ello, para hacer cumplir su implementación en todos y cada uno de los artilugios. –

+1

Entonces sí, definitivamente debería tener IWidget1 derivado de ICommon. – Josh

3

Utilice el Principio de sustitución de Liskov para obtener una respuesta.

Si IWidget1 se puede sustituir para todos los clientes que trabajan en términos de ICommon1, entonces podría heredar IWidget1 de ICommon1. Si no, vaya con la clase implementando múltiples interfaces.

+0

¿Eso no produce el mismo resultado? –

+0

@Tim - ¿puedes dar más detalles? Lo que quise decir es que si puede sustituir un objeto IWidget1 por todo el código que espera un ICommon1 y tiene sentido tener una entidad IWidget1 en su dominio, entonces puede ir con el enfoque de herencia de interfaz. Si no, haga que la misma clase implemente múltiples interfaces. – Gishu

+0

OK, veo lo que quieres decir. Gracias. –

0

La herencia depende del atributo/comportamiento de la clase o interfaz. Si los comportamientos en IWidget1 y IWidget2 incluyen todos los comportamientos en ICommon, entonces seguramente puede heredar como IWidget1 : ICommon y IWidget2 : ICommon y no hay ningún problema con respecto a ComVisible. Esto es simplemente el concepto OOPS.

1

Hay otra consideración que creo que no se tuvo en cuenta en las otras respuestas.

Si usted deriva IWidgetX de ICommon, y luego llegar a un widget que tiene el comportamiento de ambos IWidget1 y IWidget2 que puede hacer múltiples implementación de la interfaz:

class Widget3 : IWidget1, IWidget2 

Si ambos interfase se derivaban de ICommon, entonces tendrás dos implementaciones de ICommon en tu clase. Eso no es un gran problema y puede ser manejado por multiple interface implementation, pero cambia la lógica.

Por otro lado, si no se derivan IWidgetX de ICommon, sólo puede poner en práctica los tres y no tener que lidiar con la implementación explícita:

class Widget3 : IWidget1, IWidget2, ICommon 

lo tanto, si es concebible que pueda necesitar tal clase de Widget3 - será mejor que no obtenga las interfaces IWidgetX de ICommon

+0

+1 gracias por una nueva perspectiva útil. –

+0

Gracias Tim, ¡aunque resulta que no estoy exactamente en lo cierto! Profundicé un poco más en esta implementación de interfaz múltiple y en realidad no tienes dos implementaciones de ICommon; si lo hubieras hecho, entonces el molde (ICommon) (nuevo Widget3()) no se resolvería. Describí la situación con más detalle [en esta publicación de blog] (http://stefankiryazov.blogspot.com/2011/09/luke-whos-your-father-multiple.html) El argumento en contra de derivar IWidgetX de ICommon sigue siendo parcialmente válido aunque – Vroomfundel