2010-03-03 18 views
5

Sto implementando un insieme di classi e interfacce corrispondenti dove voglio che ogni classe abbia un insieme di proprietà comuni e un insieme di proprietà specializzate che sono specifiche solo per quella classe. Così, Sto pensando di definire le interfacce lungo le linee di:Eredità di interfaccia multipla

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

sto cercando di scegliere tra l'avere l'eredità nelle interfacce, o nella classe. Così, in particolare, posso neanche fare in questo modo:

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

... o così ...

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

C'è qualche motivo valido per andare in un modo o l'altro?

Aggiornamento: influenzerebbe la risposta se le classi devono essere COM-visibili?

risposta

6

È necessario scegliere l'ereditarietà dell'interfaccia se e solo se un tipo che implementa IWidget1 deve implementare anche ICommon. In entrambi i casi, la classe implementerà separatamente IWidget1 e ICommon. L'unica differenza è che se si rende IWidget1 "derivato" da ICommon, si impone il fatto che anche IWidget1 deve essere un ICommon.

Un buon esempio è IEnumerable e ICollection. Ogni ICollection è garantito come IEnumerable, quindi ICollection deriva da IEnumerable. Se era legale o aveva senso essere una raccolta ma non essere enumerabile, allora gli implementatori di ICollection non avrebbero dovuto implementare anche IEnumerable.

Quale che si sceglie non influirà sulla visibilità di COM. .NET continuerà ad esportare le interfacce separatamente se ricordo correttamente.

+0

Giusto, sì. Tutti i tipi di widget DEVONO implementare ICommon. Questo è il motivo per cui lo fa, per rafforzarne l'implementazione in ogni singolo widget. –

+1

Quindi sì, sicuramente dovrei avere IWidget1 derivare da ICommon. – Josh

3

Utilizzare il Principio di sostituzione di Liskov per ottenere una risposta.

Se IWidget1 può essere sostituito da tutti i client che lavorano in ICommon1, è possibile ereditare IWidget1 da ICommon1. Se non vai con la classe implementando più interfacce.

+0

Non produce lo stesso risultato? –

+0

@ Tim: puoi elaborare? Quello che intendevo era che se è possibile sostituire un oggetto IWidget1 per tutto il codice che si aspetta un ICommon1 e ha senso avere un'entità IWidget1 nel proprio dominio, allora si può andare con l'approccio di ereditarietà dell'interfaccia. Altrimenti, avere la stessa classe implementare più interfacce. – Gishu

+0

OK Capisco cosa intendi. Grazie. –

0

L'ereditarietà dipende dall'attributo/comportamento della classe o dell'interfaccia. Se i comportamenti in IWidget1 e IWidget2 includono tutti i comportamenti in ICommon, allora si può sicuramente ereditare come IWidget1 : ICommon e IWidget2 : ICommon e non vi è alcun problema riguardante ComVisible. Questo è semplicemente il concetto di OOPS.

1

C'è un'altra considerazione che penso non sia stata presa in considerazione nelle altre risposte.

Se si deriva IWidgetX da ICommon, e poi arriva con un widget che ha il comportamento di entrambi IWidget1 e IWidget2 si può fare implementazione dell'interfaccia multipla:

class Widget3 : IWidget1, IWidget2 

Se entrambi interfaccia erano stati ricavati da ICommon, allora avrai due implementazioni di ICOMON nella tua classe. Questo non è un grosso problema e può essere gestito da multiple interface implementation, ma cambia la logica.

D'altra parte, se non derivano IWidgetX da ICommon, si può semplicemente implementare tutti e tre e non avere a che fare con esplicito implementazione:

class Widget3 : IWidget1, IWidget2, ICommon 

Quindi, se è concepibile che potrebbe essere necessario tale classe Widget3 - è meglio non derivare le interfacce IWidgetX da ICommon

+0

+1 grazie per una nuova prospettiva utile. –

+0

Grazie Tim - anche se si scopre che non ho esattamente ragione! Ho scavato un po 'più a fondo in questa cosa di implementazione dell'interfaccia multipla e in realtà non hai due implementazioni di ICommon - se lo avessi, allora il cast (ICommon) (nuovo Widget3()) sarebbe irrisolvibile. ho descritto la situazione in modo più dettagliato [in questo post del blog] (http://stefankiryazov.blogspot.com/2011/09/luke-whos-your-father-multiple.html) L'argomento contro derivante da IWidgetX ICommon è ancora parzialmente valido però – Vroomfundel

Problemi correlati