2010-10-05 11 views
5

Czy jesteś w stanie zdefiniować implementacje klas w interfejsie?Definiowanie implementacji klas w interfejsie

Na przykład alert (pseudo-kod!) ...

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; } 
    } 
} 

Odpowiedz

4

Celem interfejsu jest zdefiniowanie kontrakt, który jest niezależny od jakiejkolwiek realizacji.

Co można zrobić z interfejsem jest zdefiniowanie własność tak:

interface IClass1 
{ 
    String S { get; set; } 

    Class2 SubClass { get; set; } 
} 
+0

@roosteronacid: Jest to preferowana odpowiedź? – cseder

3

nr Również Class2 nie jest podklasą, to zagnieżdżona klasa lub klasa wewnętrzna. "Podklasa" to (w tym kontekście istnieją inne konteksty, które są całkowicie różne) inna nazwa dla klasy pochodnej, w której kontekście klasa podstawowa jest nazywana "super-klasą" (dlatego Java ma słowo kluczowe super to jest analogiczne do base w C#, choć z pewnymi różnicami). "Derived" i "base" są bardziej popularnymi terminami w języku C#, być może dlatego, że są bardziej popularne w C++, być może dlatego, że Bjarne Stroustrup twierdzi, że są one mylące i nawet on się miesza, o co chodzi (w końcu, podklasa ma nadzbiór zachowania i odwrotnie).

Klasy wewnętrzne zasadniczo używają swojej klasy zawierającej jako przestrzeni nazw i niczego innego, podczas gdy interfejsy zawierają tylko szczegóły metod i właściwości członków.

2

Nie ma składni wymuszającej na klasie implementację innej zagnieżdżonej klasy. Rzeczywiście zdefiniowano tutaj, że każda implementacja IClass1 musi mieć pole typu Class2.

Niestety istnieją dwie rzeczy złego w tym:

  1. Class2 nie rozwiąże do znanej dostępnym typu, dlatego zostanie wygenerowany błąd kompilatora.
  2. Członek SubClass z IClass1 jest zadeklarowany jako pole, a interfejsy nie mogą zadeklarować pól.
1

Przede wszystkim, pytanie: „Czy jesteś w stanie zdefiniować klasy implementacje w interfejsie? "

Odpowiedź brzmi: "w sposób/nie".
Nie można uwzględnić definicji klas "wewnątrz" definicji interfejsu, jeśli o to chodzi.

Jak wspomniano wcześniej, implementacja takiej rzeczy może się zdarzyć poprzez właściwości interfejsu.

Prawdopodobnie nie powinieneś próbować implementować opisanej struktury interfejsu, chyba że istnieją klasy, w których funkcjonalność kodu implementującego jest całkowicie zależna i czy interfejs jest już głęboko zintegrowany z kilkoma istniejącymi modułami. To samo w sobie jest wadą projektową i można go zastąpić implementacją klasy abstrakcyjnej.
Środowisko CLR nie obsługuje dziedziczenia wielokrotnego, ale pozwala typom implementować jeden lub więcej interfejsów oprócz dziedziczenia z klasy bazowej.Dlatego interfejsy są często używane do osiągnięcia efektu dziedziczenia wielokrotnego.

Wymaganie, aby klasy dziedziczyły z pojedynczej klasy bazowej, w większości przypadków sprawiłoby, że hierarchia klas była zbyt nieelastyczna. Aby wewnętrznie używać klasy bazowej w celu uproszczenia rozwoju biblioteki, członkowie publiczni powinni delegować pracę do klasy bazowej zamiast dziedziczyć z niej. Starannie wybrać między klasy abstrakcyjnej i interfejs przy projektowaniu abstrakcję jak może zachowywać się jak interfejs w to, że może zdefiniować członków, a to może podać szczegóły implementacji ale nie jest to wymagane, a może dodać członków, ile potrzeba wspierać dodatkową funkcjonalność ...

Więc, jeśli są stosowane w sposób, który chcesz, to odchodzi od koncepcji interfejsów C#, ale może wydawać się bliżej naśladować model dziedziczenia wielu języków takich jak: C++ w praktyce, ponieważ niejawnie "zmusza wszystkich implementatorów interfejsu do tworzenia instancji każdej klasy, która ma specyfikację interfejsu d właściwości dla.
Musisz trochę pomyśleć o powodzie, dla którego chcesz utworzyć taką strukturę (potrzeba wymuszenia wszystkich implementatorów interfejsu, aby utworzyć także wystąpienia klas, które interfejs definiuje jako właściwości).
Jest to bardziej prawdopodobne, błąd projektowy w kodzie niż brakująca funkcja językowa.

Więc nawet jeśli jest to możliwe obejście, nie nazwałbym go dobrym sposobem projektowania rzeczy ...

2

Przeprosiny jakbym źle zrozumieli, ale tak, mogę to zrobić teraz (VB 2013 do .NET 4.0 & 4.5). Interfejsy mogą definiować właściwości, właściwości mogą być złożone, a definicja klasy może być zagnieżdżona w definicji interfejsu. W twojej klasie, która implementuje interfejs, możesz mieć tylko obiekt pobierający/ustawiający dla złożonego obiektu jako całości, a nie dla jego indywidualnych właściwości. (Pozyskiwanie/ustawianie dla tych jest oczywiście w ramach definicji klasy). Przykład zastosowania z dołączonego VB, wraz z nieprzetestowaną konwersją do 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 

i 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 - wersja C# nie będzie się kompilować. C# nie pozwala na klasy w interfejsach. –

Powiązane problemy