it-swarm.com.de

Wie kann man zwischen einer Schnittstelle oder Basisklasse für eine neue Implementierung entscheiden?

Wie sollte ich mich bei der Implementierung für einen Basistyp oder eine Schnittstelle entscheiden? Ich habe versucht, an wenigen Beispielen zu arbeiten, bekomme aber nicht die vollständige Idee :(

Beispiele, wie und warum sehr geschätzt werden würde ..

28
Sakthivel

Eine Basisklasse (abstrakt oder nicht) kann implementierte Member enthalten. Eine Schnittstelle kann nicht. Wenn alle Ihre Implementierungen ähnlich funktionieren, kann eine Basisklasse der richtige Weg sein, da alle Ihre untergeordneten Klassen dieselben Implementierungen der Member der Basisklasse verwenden können. Wenn sie keine Implementierungen gemeinsam nutzen wollen, könnte eine Schnittstelle der richtige Weg sein.

Beispiel:

class Person
{
    string Name { get; set; }
}

class Employee : Person
{
    string Company { get; set; }
}

Es ist sinnvoll, dass Employee von Person erbt, da die Employee-Klasse keine Name-Eigenschaft definieren muss, da sie die Implementierung gemeinsam nutzt.

interface IPolygon
{
    double CalculateArea()
}

class Rectangle : IPolygon
{
    double Width { get; set; }
    double Height { get; set; }

    double CalculateArea()
    {
        return this.Width * this.Height;
    }
}

class Triangle : IPolygon
{
    double Base { get; set; }
    double Height { get; set; }

    double CalculateArea()
    {
        return 0.5 * this.Base * this.Height;
    }
}

Da Rectangle und Triangle solche unterschiedlichen Implementierungen von CalculateArea haben, ist es für sie nicht sinnvoll, von einer Basisklasse zu erben.

Wenn Sie eine Basisklasse erstellen und in only abstrakte Elemente finden, können Sie auch einfach eine Schnittstelle verwenden.

Mit j__m können Sie nicht von mehreren Basisklassen erben, Sie können jedoch mehrere Schnittstellen implementieren.

Normalerweise definiere ich zunächst Schnittstellen. Wenn ich in meinen Implementierungen Code dupliziere, erstelle ich eine Basisklasse, die die Schnittstelle implementiert, und erzwinge, dass meine Implementierungen davon erben.

39
Dan

Um zu entscheiden, ob Sie eine abstrakte Klasse oder ein Interface verwenden, finde ich diesen Artikel sehr hilfreich. Source :

Ein guter Weg, um zwischen einem Fall für den einen oder anderen Fall zu unterscheiden, war für mich immer Folgendes:

  1. Gibt es viele Klassen, die "gruppiert" und durch ein noun beschrieben werden können? Wenn ja, haben Sie eine abstrakte Klasse mit dem Namen dieses Substantivs und erben Sie die Klassen davon. (Ein entscheidender Entscheider ist, dass diese Klassen Funktionalität gemeinsam nutzen, und Sie würden niemals nur Animal instanziieren ... Sie würden immer eine bestimmte Art von Animal instanziieren: eine Implementierung Ihrer Animal -Basis Klasse) Beispiel: Cat und Dog können beide von der abstrakten Klasse Animal erben, und diese abstrakte Basisklasse implementiert eine Methode void Breathe (), die alle Tiere machen es also auf die gleiche Weise. (Ich könnte diese Methode virtuell machen, damit ich sie für bestimmte Tiere wie Fisch außer Kraft setzen kann, der nicht so atmet wie die meisten Tiere).

  2. Welche Arten von Verben können auf meine Klasse angewendet werden, die im Allgemeinen auch auf andere angewendet werden können? Erstellen Sie eine Schnittstelle für jedes dieser Verben . Beispiel: Alle Tiere können gefüttert werden, also werde ich eine Schnittstelle mit dem Namen IFeedable erstellen und Animal dies implementieren lassen. Nur Dog und Horse sind zwar nett genug, um ILikeable zu implementieren - ich werde dies nicht in der Basisklasse implementieren, da dies nicht für Cat gilt.

Bitte beachten Sie auch diese Schnittstelle vs. Basisklasse - Frage.

18
Alina B.

Ein Grund für die Verwendung von abstrakten Klassen ist, dass wir eine Initialisierung erzwingen müssen (wie Zustände über den Konstruktor).

Die Schnittstelle erlaubt Ihnen nicht, die Verträge von Constructor zu definieren.

Im folgenden Beispiel sollte jedes Animal-Objekt einen NAMEN haben. Dies kann nicht über eine Schnittstelle erzwungen werden.

public abstract class Animal
{
    public Animal(string name)
    {
        this.Name = name;
    }

    public string Name 
    { 
        get; 
        private set; 
    }
}

public class Cat : Animal
{
    public Cat(string name)
        : base(name)
    {

    }

    string NoOfLegs { get; set; }
}



class Program
{
    static void Main(string[] args)
    {
        Animal aCat = new Cat("a");
    }
}
4
jacob aloysious

Eigentlich schließen sie sich nicht unbedingt aus. Sie können beide verwenden, je nachdem, wie sich Ihre Codeimplementierung entwickelt.

Eine Schnittstelle ist normalerweise die Anzeige eines Vertrags. Es definiert ein erwartetes Verhalten, das die Implementierer einhalten sollten. Es ist in der Regel eine gute Praxis, Ihre public api against Interfaces zu codieren. Auf diese Weise reduzieren Sie die Kopplung auf die Details Ihrer Implementierungen und ermöglichen eine einfachere Umgestaltung und Wartung Ihres Codes. Was nun als öffentliches API bezeichnet wird, sind Softwarekomponenten, die die in Ihrem Entwurf definierte Interaktion auf hoher Ebene verkörpern und entweder von Ihnen selbst und anderen innerhalb desselben Projekts oder innerhalb mehrerer Projekte mit unabhängigem Umfang wiederverwendet werden sollen.

Eine Basisklasse ist bereits Teil der Implementierung . Ob eine Schnittstelle implementiert wird oder nicht. Und es verknüpft seine potenzielle Hierarchie mit bestimmten Implementierungsdetails: Objektstatus, überschreibbare oder nicht überschreibbare Methoden usw.

3
ylabidi

Schnittstellen sind ein flexibleres Konstrukt. Sie können nur eine Basisklasse haben, aber Sie können viele Schnittstellen implementieren. Wenn Sie ein Objekt benötigen, das mehrere Verhalten unterstützt, aber für mehr als eines dieser Verhalten eine bestimmte Basisklasse erforderlich ist, können Sie dies nicht tun.

Wie Dan-Notes erwähnt, haben Basisklassen in vielen Sprachen den Vorteil, dass Sie eine Basisimplementierung bereitstellen können. Um dies mit einer Schnittstelle zu tun, müssen Sie eine Klasse erstellen, die die Basisimplementierung bereitstellt, und anschließend Ihre Implementierung jeder Schnittstellenmethode manuell an diese Klasse delegieren.

2
j__m

Ich finde hier eine Analogie hilfreich:

Zusammenfassung Basisklasse: - Ein Automobilhersteller entwickelt möglicherweise einen Benzinmotor mit einigen Varianten (1.6, 2L usw.). Das Motorblockgießen könnte als abstrakte Basisklasse betrachtet werden, d. H. Es definiert die Grundform und die Merkmale des Motors. Eine 2L-Version kann einen größeren Zylinderkopf haben usw. 

Schnittstellen: . Die Engine kann auch verschiedene Standardkomponenten verwenden, z. Lichtmaschine, Kühler, Anlasser usw. und so muss es Interfaces implementieren, die von diesen Komponenten definiert werden. Diese Komponenten wurden normalerweise ohne Kenntnis der Motoren entwickelt, die sie möglicherweise verwenden.

1
Adrian

Sie können grundsätzlich beide zusammen verwenden, wenn Sie benötigen. Im Allgemeinen können Sie die Basisklasse jedoch für einige Methoden oder Eigenschaften verwenden, die Sie auch in geerbten Klassen verwenden. Wenn Sie eine Basisklasse erstellen, ist es besser, sie zu abstrahieren. Dann sind Sie flexibler, wenn Sie virtuelle Methoden in der Basisklasse verwenden und diese in geerbten Klassen überschreiben und auf andere Weise verwenden.

Mit Schnittstellen sind Sie flexibler. Zunächst machen Sie eine Deklaration zwischen Klassen, die von dieser Schnittstelle geerbt wurden. Mit diesem

  • sie verbessern die Lesbarkeit Ihres Codes
  • sie trennen Ihre Konzepte, wie eine von Schnittstelle A geerbte Klasse eine Verbindung zur Mssql-Datenbank herstellen kann, während eine andere eine Verbindung zur Mysql-Datenbank herstellen kann.
  • ihr Code wird einfacher zu verwalten. Interfaces helps to reduce coupling and therefore allow you to easily interchange implementations for the same concept without the underlying code being affected
  • Sie können Abhängigkeitsinjektion verwenden
  • Sie können einfacher Unittest erstellen.

    Sie können einen Blick werfen diese Frage hier für weitere Informationen.

0
nzrytmn