2010-07-11 18 views
8

Ich habe eine Schnittstelle, damit Klassenschreiber bestimmte Methoden implementieren müssen. Ich möchte auch einige standardmäßig implementierte Methoden erlauben, also erstelle ich eine abstrakte Klasse. Das Problem ist, dass alle Klassen von der Basisklasse erben, also habe ich einige Hilfsfunktionen dort.abstrakte Klasse implementiert keine Schnittstelle

Ich habe versucht, schreiben Sie an: IClass in der abstrakten Basis aber ich habe einen Fehler, dass die Basis nicht die Schnittstelle implementieren haben. Nun, natürlich, weil ich diese Zusammenfassung möchte und die Benutzer diese Methoden implementieren lassen. Als Rückgabeobjekt, wenn ich Base benutze, kann ich die Methoden der Interface-Klasse nicht aufrufen. Wenn ich die Schnittstelle verwende, kann ich nicht auf Basismethoden zugreifen.

Wie mache ich es so kann ich diese Hilfsklassen und Kraft müssen Benutzer bestimmte Methoden zu implementieren?

Antwort

6

Verschieben Sie die Interface-Methoden in die abstrakte Klasse und deklarieren Sie sie ebenfalls als abstrakt. Dadurch sind abgeleitete Klassen gezwungen, diese zu implementieren. Wenn Sie Standardverhalten verwenden möchten, verwenden Sie abstrakte Klassen. Wenn Sie nur die Signatur fixieren möchten, verwenden Sie eine Schnittstelle. Beide Konzepte vermischen sich nicht.

15

Stellen Sie sicher, dass Methoden in der Basisklasse denselben Namen wie die Schnittstelle haben und öffentlich sind. Machen Sie sie auch virtuell, damit Unterklassen sie überschreiben können, ohne sie zu verbergen.

interface IInterface { 
    void Do(); 
    void Go(); 
} 

abstract class ClassBase : IInterface { 

    public virtual void Do() { 
     // Default behaviour 
    } 

    public abstract void Go(); // No default behaviour 

} 

class ConcreteClass : ClassBase { 

    public override void Do() { 
     // Specialised behaviour 
    } 

    public override void Go() { 
     // ... 
    } 

} 
0

Nachdem ich kürzlich mit dem gleichen Problem konfrontiert wurde, habe ich mir eine etwas elegantere (meiner Meinung nach) Lösung ausgedacht. Es sieht aus wie:

public interface IInterface 
{ 
    void CommonMethod(); 
    void SpecificMethod(); 
} 

public abstract class CommonImpl 
{ 
    public void CommonMethod() // note: it isn't even virtual here! 
    { 
     Console.WriteLine("CommonImpl.CommonMethod()"); 
    } 
} 

public class Concrete : CommonImpl, IInterface 
{ 
    void SpecificMethod() 
    { 
     Console.WriteLine("Concrete.SpecificMethod()"); 
    } 
} 

nun nach C# spec (. 13.4.4 Interface-Mapping), in dem Prozess der Zuordnung IInterface auf Concrete Klasse, Compiler für CommonMethod in CommonImpl sehen, und es doesn‘ t muss sogar in der Basisklasse virtuell sein!

Der andere wesentliche Vorteil gegenüber Mau-Lösung ist, dass Sie müssen nicht jedes Schnittstelle Mitglied in der abstrakten Basisklasse auflisten.

+0

Ich bevorzuge Mau's Lösung. Es ist explizit und lässt den Compiler die Konformitätsarbeit für Sie erledigen. In dieser Lösung könnten Sie vergessen, das IInterface zu der abgeleiteten Klasse hinzuzufügen. – PlayTank

+0

@PlayTank: ... und dann scheitert es schließlich an einer impliziten Konvertierung, auch zur Kompilierzeit. Obwohl ich zustimme, fehlt der Lösung eine gewisse artikulierte Strenge. – vines

Verwandte Themen