| 

.NET C# Java Javascript Exception

4
Ich will in einem Interface definieren, dass eine Klasse immer einen Konstruktor haben muss mit einer ganz bestimmten Parameterliste.

Etwa so.

using System;
interface IInterface
{
void ctor(string etwas);
}
public class Class1 : IInterface
{
public Class1(){}
public Class1(string etwas){}
}
public class Class2 : IInterface
{
public Class2(){}
public Class2(string etwas){}
}


Wie sieht ein solches Interface aus?
28.08.2009
GENiALi 2,5k 1 2 8
5 Antworten
8
AFAIK, Nein.

Die Doku zur Beschreibung eines Interface sagt:

"Eine Schnittstelle kann ein Member eines Namespaces oder einer Klasse sein und Signaturen der folgenden Member enthalten:
Methoden
Eigenschaften
Indexer
Ereignisse
"

Servus,
Klaus
28.08.2009
klaus_b 1,6k 3 7
2
Ein Konstruktor kann wie bereits erwähnt nicht in der Schnittstelle definiert werden. Möglich ist jedoch die Definition einer Fabrik welche das Objekt erzeugt - bringt aber nichts denn die Fabrikmethode sollte statisch sein und das geht mit Schnittstellen ebenfalls nicht.

Das einzige wo das möglich ist sind abstrakte Klassen - dabei muss jedoch die Vererbungshierarchie in Betracht gezogen werden.
28.08.2009
gfoidl 9,4k 3 5
2
Konstruktoren gehen zu stark auf die konkrete Verwendung ein und stehen damit dem Schnittstellenprinzip entgegen. Schnittstellen sind für starke polymorphe Anwendungen gedacht. Wenn man Konstruktoren allgemein definieren möchte aber die Implementation konkreter Sachverhalte spezielleren Klassen überlassen möchte, sind wahrscheinlich abstrakte Klassen die bessere Wahl...

...es sei denn man hat sich in der Vererbungshierarchie mit abstrakten Klassen die Möglichkeit genommen... Abstrakte Klassen sollte man dann verwenden, wenn die Vererbungshierarchie wenigen Änderungen unterliegt, also eher eine schwache Polymorphie aufweist. Der Wunsch einen vordefinierten Konstruktor zu verwenden ist ein Indiz dafür, dass man eine abstrakte Klasse verwenden sollte.

Beispiel "Iterator". Hierbei handelt es sich um ein Interface, weil man im Prinzip über "Hans und Pup" iterieren möchte. Die stark polymorphe Ausprägung der Verwendung bedingt eine Schnittstelle.

Fazit: Vergiss das mit den Konstruktorensignaturen in Interfaces.
13.05.2011
oopexpert 455 1 8
2
Auch wenn es eine recht alte Frage ist, ist diese dennoch sehr interessant. Unabhängig von irgendwelchen MSDN Artikeln die besagen, dass das nicht geht, könnte man das Pferd ja einmal von hinten aufzäunen.

Kurzum handelt es sich bei einem Konstruktor um nichts anderes als eine Instanzmethode. Der Konstruktor ist nicht statisch und kann sich auf die Instanz (this) beziehen. Es spräche also nichts dagegen, einem Interface IApp einen Konstruktor "ctor(int)" zu geben. Natürlich ohne Implementierung, aber die Signatur.

Nun kann eine Klasse MyApp die Interfaces IApp und ICoolApp implementieren. Das bedeutet, dass die Klasse MyApp zwei Konstruktoren hat. Falls die Konstruktoren aus den Interfaces die gleiche Signatur aufweisen "ctor(int)", kann man diese wie bei "normalen" Methoden auch explizit implementieren.

Wir nehmen einmal an, die Klasse IApp hat den Konstruktor "ctor(int)" und ICoolApp den Konstruktor "ctor(string)". Die Klasse MyApp impementiert IApp und ICoolApp und hat zwei Konstruktoren definiert. Soweit alles gut, aber jetzt kommt das Problem.

Der Aufruf des Konstruktor findet durch das Schlüsselwort "new" statt und wird nicht explizit aufgerufen. Ich kann also mit "new MyApp(string)" eine MyApp instanziieren und habe damit sowohl ein IApp also auch ein ICoolApp. Oder auch nicht! Denn beim Instanziieren der Klasse habe ich nur einen Vertrag erfüllt, nämlich den von ICoolApp. Den im Vertrag geforderten Konstruktor von IApp habe ich nicht erfüllt.

Also: Ist die Instanz von MyApp nun ein IApp oder nur ein ICoolApp?

http://blackbeltprogrammer.blogspot.de/2014/07/why-interfaces-cannot-define.html
07.07.2014
ThomasMentzel 123 5
1
Sehr interessant. Auf diese Überlegung bin ich noch garnicht gekommen.

(kann leider immernoch kein +1 vergeben :/)
Floyd 08.07.2014
"Kurzum handelt es sich bei einem Konstruktor um nichts anderes als eine Instanzmethode."
^^^^^^^
Auf welcher Instanz soll die aufgerufen werden??? Der Konstruktor dient ja gerade dazu, die Instanz zu erzeugen.
Auch Dein 2. Argument läuft für mich ins Leere. Wenn MyApp beide Interfaces implementiert, ist es "vertraglich gebunden", beide Konstruktoren anzubieten und beide so zu implementieren, daß jeweils ein Objekt entsteht, dass beide Interfaces implementiert. Mehr nicht. Kein Interface kann verlangen, daß eine Funktionalität nur durch eine bestimmte Methode bereitgestellt werden kann.
Matthias Hlawatsch 17.07.2014
Grr, dieser Editor...
Die Hervorhebung galt dem "Instanz" in "Instanzmethode"...
Matthias Hlawatsch 17.07.2014
@Matthias, Absatz 2: Was wenn aber wenn ich des Kunstruktor aus dem Interface IA aufrufe, mir dabei aber nicht alle Informationen für IB zur verfügung stehen. Gerade beim Interface-Segregation-Prinzip kann das sehr schnell eintreten.

Konstruiertes Beispiel:
IDb { .ctr(IRepresetory r) }
IAudit { .ctr(IAudit a) }
class abc : IDb, IAudit {
//..
}
Floyd 17.07.2014
Komischer Satzbau im ersten Satz .. :/
Floyd 17.07.2014
Das ist ein Problem, das der Implementierer der Klasse abc lösen muß. Das kann im Einzelfall schwierig bis nicht sinnvoll sein, syntaktisch möglich ist es immer (schlimmstenfalls mit dem Holzhammer der NotSupportedException).
Mir ging es nur darum, daß es völlig legal wäre, den IA.ctr() so zu implementieren, daß die erzeugte Instanz "nebenbei" auch IB erfüllt, *ohne* dabei den IB.ctr() aufzurufen.
Matthias Hlawatsch 17.07.2014
1
Aber eigentlich diskutieren wir hier über ein Quadrat mit 3 Ecken. Interfaces beschreiben, was eine Objekt-Instanz leistet, wenn sie denn einmal da ist. Konstruktoren sind Fabriken für die Instanzen, aber sie gehören der Klasse. Sobald die Instanz da ist, sobald also das Ding da ist, das den Vertrag erfüllen muß, hat der Konstruktor seine Arbeit schon getan. Folglich kann der Konstruktor im Interface keinen Sinn haben, und eine was-wäre-wenn-Diskussion auch nicht.
Matthias Hlawatsch 17.07.2014
1
Scheint nicht zu funktionieren. Habe hier noch eine Diskussion zum Thema gefunden.

Eventuell könnte es mit generischen Interfaces klappen. Mal genauer anschauen.
28.08.2009
GENiALi 2,5k 1 2 8
Da meine Antwort also richtig zu schein seint, wöhre es nett wen du sie auch akzeptieren würdest :-)
klaus_b 28.08.2009

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH