2010-03-03 1 views
5

Ich implementiere eine Reihe von Klassen und entsprechenden Schnittstellen, wo ich möchte, dass jede Klasse eine Reihe von allgemeinen Eigenschaften und eine Reihe von speziellen Eigenschaften, die nur für diese Klasse spezifisch sind. Also, ich bin unter Berücksichtigung Schnittstellen entlang der Linien definieren:Mehrere Schnittstellenvererbung

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

ich zwischen mit der Vererbung in den Schnittstellen, oder in der Klasse zu wählen versuche. Also, gesagt, ich kann entweder tun es wie folgt aus:

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

... oder so ...

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

Gibt es einen zwingenden Grund, die eine oder die andere zu gehen?

Update: Würde es die Antwort beeinflussen, wenn die Klassen COM-sichtbar sein müssen?

Antwort

6

Sie sollten die Schnittstellenvererbung auswählen, wenn und nur wenn ein Typ implementiert IWidget1 muss auch implementieren ICommon. In beiden Fällen wird die Klasse sowohl IWidget1 als auch ICommon separat implementieren. Der einzige Unterschied besteht darin, dass Sie, wenn Sie IWidget1 von ICommon "ableiten" lassen, die Tatsache durchsetzen, dass ein IWidget1 auch ein ICommon sein muss.

Ein gutes Beispiel ist IEnumerable und ICollection. Jede ICollection ist garantiert IEnumerable, daher stammt ICollection von IEnumerable. Wenn es legal oder sinnvoll wäre, eine Sammlung zu sein, aber nicht aufzählbar zu sein, dann müssten die Implementierer von ICollection auch IEnumerable nicht implementieren.

Welches Sie auch wählen, hat keinen Einfluss auf die COM-Sichtbarkeit. .NET wird die Schnittstellen weiterhin separat exportieren, wenn ich mich richtig erinnere.

+0

Recht, ja. Alle Widget-Typen MÜSSEN ICommon implementieren. Das ist der Grund dafür, seine Implementierung in jedem Widget zu erzwingen. –

+1

Dann ja, du solltest definitiv IWidget1 von ICommon ableiten. – Josh

3

Verwenden Sie das Liskov Substitutionsprinzip, um sich selbst eine Antwort zu geben.

Wenn IWidget1 für alle Clients ersetzt werden kann, die in ICommon1 arbeiten, können Sie IWidget1 von ICommon1 erben. Wenn nicht mit der Klasse gehen, die mehrere Schnittstellen implementiert.

+0

Führt das nicht zum selben Ergebnis? –

+0

@Tim - können Sie das ausarbeiten? Was ich meinte war, dass, wenn Sie ein IWidget1-Objekt für den gesamten Code ersetzen können, der ICommon1 erwartet, und es sinnvoll ist, eine IWidget1-Entität in Ihrer Domäne zu haben, dann können Sie mit dem Interface-Vererbungsansatz gehen. Wenn nicht, muss die gleiche Klasse mehrere Schnittstellen implementieren. – Gishu

+0

OK ich sehe was du meinst. Vielen Dank. –

0

Die Vererbung hängt vom Attribut/Verhalten der Klasse oder der Schnittstelle ab. Wenn die Verhaltensweisen in IWidget1 und IWidget2 alle Verhaltensweisen in ICommon enthalten, dann können Sie sicherlich wie IWidget1 : ICommon und IWidget2 : ICommon erben und es gibt kein Problem bezüglich ComVisible. Das ist einfach OOPS-Konzept.

1

Es gibt eine andere Überlegung, die in den anderen Antworten meiner Meinung nach nicht berücksichtigt wurde.

Wenn Sie IWidgetX von ICommon ableiten, und dann mit einem Widget kommen, die das Verhalten von sowohl IWidget1 und IWidget2 hat mehrere Schnittstellen-Implementierung können:

class Widget3 : IWidget1, IWidget2 

Wenn beide waren Schnittstelle von ICommon abgeleitet wurden, Dann haben Sie zwei Implementierungen von ICommon in Ihrer Klasse. Das ist kein großes Problem und kann von multiple interface implementation behandelt werden, aber es ändert die Logik.

Auf der anderen Seite, wenn Sie IWidgetX von ICommon nicht ableiten, können Sie einfach alle implementieren drei und nicht mit der expliziten Umsetzung zu tun haben:

class Widget3 : IWidget1, IWidget2, ICommon 

Also, wenn es denkbar ist, dass Sie benötigen Solche Widget3-Klasse - Sie sollten besser nicht die IWidgetX-Schnittstellen von ICommon

+0

+1 danke für eine nützliche neue Perspektive. –

+0

Danke Tim - obwohl es sich herausstellt, dass ich nicht genau richtig bin! Ich habe ein wenig tiefer in diese Multiple-Interface-Implementierungs-Sache gegraben und tatsächlich gibt es nicht zwei Implementationen von ICommon - wenn du es getan hättest, wäre die Besetzung (ICommon) (neues Widget3()) nicht lösbar. Ich beschrieb die Situation detaillierter [in diesem Blogpost] (http://stefankiryazov.blogspot.com/2011/09/luke-whos-your-father-multiple.html) Das Argument gegen IWidgetX von ICommon abgeleitet ist jedoch noch teilweise gültig – Vroomfundel

Verwandte Themen