2010-10-05 8 views
5

Können Sie Klassenimplementierungen in einer Schnittstelle definieren?Klassenimplementierungen in einer Schnittstelle definieren

Zum Beispiel (Pseudo-Code Alarm!) ...

interface IClass1 
{ 
    String s { get; set; } 

    // classes implementing this interface has to implement Class2 as "SubClass" 
    Class2 SubClass; 
} 

interface IClass2 
{ 
    Int32 i { get; set; } 
} 

class Class1 : IClass1 
{ 
    String IClass1.s { get; set; } 

    class IClass1.Class2 SubClass 
    { 
     Int32 IClass2.i { get; set; } 
    } 
} 

Antwort

4

Der Zweck einer Schnittstelle ist ein Vertrag die von jeder Implementierung getrennt zu definieren.

Was Sie mit einer Schnittstelle tun können, ist, die eine Eigenschaft wie so:

interface IClass1 
{ 
    String S { get; set; } 

    Class2 SubClass { get; set; } 
} 
+0

@roosteronacid: Ist das Ihre gewünschte Antwort? – cseder

3

Nr Auch ist Class2 keine Unterklasse, es ist eine verschachtelte Klasse oder innere Klasse. "Unterklasse" ist (in diesem Kontext gibt es andere Kontexte, die völlig verschieden sind) ein anderer Name für eine abgeleitete Klasse, in welchem ​​Kontext die Basisklasse eine "Superklasse" genannt wird (weshalb Java ein Schlüsselwort super hat das ist analog zu base in C# obwohl mit einigen Unterschieden). "Abgeleitete" und "Basis" sind die populäreren Begriffe in C#, vielleicht weil sie in C++ populärer sind, vielleicht weil Bjarne Stroustrup sagt, dass er sie verwirrend findet und selbst er verwirrt darüber, was (was schließlich die Unterklasse hat eine Obermenge von Verhalten und umgekehrt).

Inner Klassen verwenden im Wesentlichen ihre containing-Klasse als Namespace und nichts anderes, während Schnittstellen nur Member-Methoden und -Eigenschaften detailliert.

2

Es gibt keine Syntax zum Erzwingen einer Klasse zum Implementieren einer anderen geschachtelten Klasse. Was Sie hier effektiv definiert haben, ist, dass jede IClass1 Implementierung ein Feld vom Typ Class2 haben muss.

Leider gibt es zwei Dinge falsch mit diesem:

  1. Class2 nicht auf eine bekannte zugängliche Art zu lösen, damit ein Compiler-Fehler generiert.
  2. Das SubClass Mitglied von IClass1 ist als ein Feld deklariert, und Schnittstellen können keine Felder deklarieren.
1

Zunächst einmal Ihre Frage ist: „können Sie Klasse-Implementierungen in einer Schnittstelle definieren? "

Die Antwort darauf ist "in einer Art und Weise/nein".
Sie können keine Klassendefinitionen "inside" die Schnittstellendefinition einschließen, wenn das das ist, was Sie meinen.

Wie bereits erwähnt, könnte die Implementierung einer solchen Sache über Schnittstelleneigenschaften geschehen.

Sie sollten wahrscheinlich nicht versuchen, Ihre beschriebene Schnittstellenstruktur zu implementieren, es sei denn Klassen existieren, dass die Funktionalität des implementierenden Codes völlig davon abhängt und wenn die Schnittstelle bereits tief in mehrere vorhandene Module integriert ist. Das in sich selbst ist ein Designfehler und könnte mit einer abstrakten Klassenimplementierung vertauscht werden.
Die CLR unterstützt keine Mehrfachvererbung, erlaubt jedoch Typen, zusätzlich zu einer Basisklasse eine oder mehrere Schnittstellen zu implementieren.Daher werden häufig Schnittstellen verwendet, um den Effekt der Mehrfachvererbung zu erzielen.

Das Angeben von Klassen, die von einer einzelnen Basisklasse erben, würde in den meisten Fällen die Klassenhierarchie zu unflexibel machen. Um eine Basisklasse intern zu verwenden, um die Bibliotheksentwicklung zu vereinfachen, sollten öffentliche Mitglieder Arbeit an die Basisklasse delegieren, anstatt von ihr zu erben. Wählen Sie sorgfältig zwischen einer abstrakten Klasse und einer Schnittstelle, wenn eine Abstraktion entwerfen, wie es in wie eine Schnittstelle verhalten kann, dass es kann Mitglieder definieren, und es kann Implementierungsdetails zur Verfügung stellt, sind aber nicht so tun erforderlich und kann Mitglieder hinzufügen, um benötigte zusätzliche Funktionalität zu unterstützen ...

wenn also in der Art und Weise der Sie wollen, weicht sie von dem Konzept der C# Schnittstellen, aber vielleicht scheinen näher die Mehrfachvererbung Modell Sprachen zu imitieren wie C++ in der Praxis, da es implizit "alle Implementierer Ihrer Schnittstelle zwingt, eine Instanz jeder von der Schnittstelle spezifizierten Klasse zu erstellen d Eigenschaften für.

Sie müssen ein wenig darüber nachdenken, warum Sie eine solche Struktur erstellen möchten (die Notwendigkeit, alle Implementierer einer Schnittstelle zu zwingen, auch Instanzen von Klassen zu erstellen, die die Schnittstelle als Eigenschaften definiert).
Dies ist wahrscheinlich ein Konstruktionsfehler in Ihrem Code als es eine fehlende Sprachfunktion ist.

Also auch wenn es sich um eine mögliche Abhilfe ist, würde ich es nicht eine gute Art und Weise der Gestaltung Dinge nennen ...

2

Entschuldigt, wenn ich das falsch verstanden habe, aber, ja, das tue ich dies jetzt (VB 2013 .NET 4.0 & 4.5). Schnittstellen können Eigenschaften definieren, Eigenschaften können komplex sein, deren Klassendefinition innerhalb der Schnittstellendefinition verschachtelt sein kann. In Ihrer Klasse, die die Schnittstelle implementiert, können Sie nur den Getter/Setter für das komplexe Objekt als Ganzes haben, nicht für seine einzelnen Eigenschaften. (Die Getter/Setter für diese sind natürlich innerhalb der Klassendefinition). Arbeitsbeispiel von VB angehängt, zusammen mit ungetesteter Konvertierung in C#.

VB:

Interface IPrintable 
    Property Body As DocBody 

    Class DocBody 
     Property Text As String 
     Property FontSize As Single 
    End Class 
End Interface 

Class WordDoc 
    Implements IPrintable 
    Public Property WordBody As IPrintable.DocBody Implements IPrintable.Body 
End Class 

und C#:

interface IPrintable 
{ 
    DocBody Body { get; set; } 
    public class DocBody 
    { 
     public string Text { get; set; } 
     public float FontSize { get; set; } 
    } 
} 

class WordDoc : IPrintable 
{ 
    public IPrintable.DocBody WordBody { get; set; } 
    IPrintable.DocBody IPrintable.Body { 
     get { return WordBody; } 
     set { WordBody = value; } 
    } 
} 
+0

FYI - die C# -Version wird nicht kompiliert. C# erlaubt keine Klassen in Schnittstellen. –

Verwandte Themen