840 Stimmen

Schnittstelle vs. Basisklasse

Wann sollte ich eine Schnittstelle und wann eine Basisklasse verwenden?

Sollte es immer eine Schnittstelle sein, wenn ich keine Basisimplementierung der Methoden definieren möchte?

Wenn ich eine Hunde- und Katzenklasse habe. Warum sollte ich IPet anstelle von PetBase implementieren wollen? Ich kann verstehen, mit Schnittstellen für ISheds oder IBarks (IMakesNoise?), weil diese auf ein Haustier von Haustier Basis platziert werden können, aber ich verstehe nicht, welche für eine allgemeine Pet verwenden.

11 Stimmen

Nur ein Punkt, den Sie meiner Meinung nach berücksichtigen sollten - Schnittstellen können verschiedene Einschränkungen mit sich bringen, derer Sie sich möglicherweise erst in sehr späten Phasen bewusst sind. Zum Beispiel mit .NET können Sie nicht serialisieren eine Schnittstelle Mitglied Variable, so dass, wenn Sie eine Klasse Zoo und ein Mitglied Variable Array von IAnimals haben Sie nicht in der Lage, Zoo serialisieren (und das bedeutet, schreiben WebServices oder andere Dinge, die eine Serialisierung wäre ein Schmerz).

2 Stimmen

Diese Frage könnte helfen, das Konzept der Schnittstellen zu verstehen. stackoverflow.com/q/8531292/1055241

0 Stimmen

Ich bin nur neugierig. Ich traf in der CLR über C# den folgenden Auszug: I tend to prefer using the interface technique over the base type technique because the base type technique doesn’t allow the developer to choose the base type that works best in a particular situation. . Ich kann nicht begreifen, was in dem Auszug gemeint ist. Wir können einige Basistypen erstellen und für jeden von ihnen einen abgeleiteten Typ erstellen, so dass ein Entwickler einen Basistyp auswählen kann. Könnte mir bitte jemand erklären, was ich übersehe? Ich glaube, es kann ein Teil dieser Frage sein. Oder sollte ich eine andere Frage zu dem spezifischen Auszug stellen?

0voto

David Pokluda Punkte 10329

Nutzen Sie Ihr eigenes Urteilsvermögen und seien Sie klug. Tun Sie nicht immer, was andere (wie ich) sagen. Sie werden hören, dass Sie "Schnittstellen abstrakten Klassen vorziehen", aber es kommt wirklich darauf an. Es kommt darauf an, was die Klasse ist.

In dem oben genannten Fall, in dem wir eine Hierarchie von Objekten haben, ist eine Schnittstelle eine gute Idee. Die Schnittstelle hilft bei der Arbeit mit Sammlungen dieser Objekte und sie hilft auch bei der Implementierung eines Dienstes, der mit jedem Objekt der Hierarchie arbeitet. Sie definieren einfach einen Vertrag für die Arbeit mit Objekten aus der Hierarchie.

Wenn Sie hingegen eine Reihe von Diensten implementieren, die eine gemeinsame Funktionalität haben, können Sie entweder die gemeinsame Funktionalität in eine komplett separate Klasse aufteilen oder sie in eine gemeinsame Basisklasse verschieben und sie abstrakt machen, so dass niemand die Basisklasse instanziieren kann.

Bedenken Sie auch, wie Sie Ihre Abstraktionen im Laufe der Zeit unterstützen können. Schnittstellen sind fest: Sie geben eine Schnittstelle als Vertrag für eine Reihe von Funktionen frei, die jeder Typ implementieren kann. Basisklassen können im Laufe der Zeit erweitert werden. Diese Erweiterungen werden Teil jeder abgeleiteten Klasse.

0voto

Roohi Punkte 7496

Danke für Antwort an por Jon Limjap aber ich möchte einige Erläuterungen zum Konzept der Schnittstelle und der abstrakten Basisklassen hinzufügen

Schnittstellentypen vs. abstrakte Basisklassen

Angepasst an die Pro C# 5.0 und das .NET 4.5 Framework Buch.

Der Schnittstellentyp mag einer abstrakten Basisklasse sehr ähnlich sein. Erinnern Sie sich an dass eine Klasse, die als abstrakt gekennzeichnet ist, eine beliebige Anzahl von abstrakten Mitgliedern definieren kann, um eine polymorphe Schnittstelle für alle abgeleiteten Typen bereitzustellen. Aber auch wenn eine Klasse eine Reihe von abstrakten Mitglieder definiert, steht es ihr auch frei, eine beliebige Anzahl von Konstruktoren, Felddaten, nicht-abstrakten Mitgliedern (mit Implementierung), und so weiter. Schnittstellen hingegen enthalten nur abstrakte Mitgliederdefinitionen. Die polymorphe Schnittstelle, die von einer abstrakten Elternklasse eingerichtet wird, leidet unter einer wesentlichen Einschränkung dass nur abgeleitete Typen die von der abstrakten Elternklasse definierten Elemente unterstützen. Allerdings ist es in größeren Softwaresystemen ist es jedoch sehr üblich, mehrere Klassenhierarchien zu entwickeln, die keinen gemeinsamen Elternteil haben über System.Object hinaus haben. Da abstrakte Elemente in einer abstrakten Basisklasse nur für abgeleitete Typen gelten, haben wir keine Möglichkeit, Typen in verschiedenen Hierarchien so zu konfigurieren, dass sie die gleiche polymorphe Schnittstelle zu unterstützen. Nehmen wir als Beispiel an, Sie haben die folgende abstrakte Klasse definiert:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

Angesichts dieser Definition können nur Member, die CloneableType erweitern, die Methode Clone() Methode unterstützen. Wenn Sie eine neue Reihe von Klassen erstellen, die diese Basisklasse nicht erweitern, können Sie diese polymorphe Schnittstelle nicht nutzen. Vielleicht erinnern Sie sich auch daran, dass C# keine Mehrfachvererbung für Klassen unterstützt. Wenn Sie also einen MiniVan erstellen wollten, der ein Auto und ein CloneableType ist, ist dies nicht möglich:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

Wie Sie sich denken können, kommen die Schnittstellentypen zur Hilfe. Nachdem eine Schnittstelle definiert worden ist, kann sie von jeder Klasse oder Struktur in jeder Hierarchie, in jedem Namespace oder in jeder Assembly implementiert werden (geschrieben in einer beliebigen .NET-Programmiersprache). Wie Sie sehen können, sind Schnittstellen in hohem Maße polymorph. Betrachten Sie die .NET-Standardschnittstelle ICloneable, die im Namespace System definiert ist. Diese Schnittstelle definiert eine einzige Methode namens Clone():

public interface ICloneable
{
object Clone();
}

0voto

Torlack Punkte 4287

Zusätzlich zu den Kommentaren, die die IPet/PetBase-Implementierung erwähnen, gibt es auch Fälle, in denen die Bereitstellung einer Accessor-Helferklasse sehr nützlich sein kann.

Der IPet/PetBase-Stil geht davon aus, dass Sie mehrere Implementierungen haben, was den Wert von PetBase erhöht, da es die Implementierung vereinfacht. Im umgekehrten Fall oder bei einer Mischung aus beidem, wenn Sie mehrere Clients haben, kann die Bereitstellung einer Klasse, die bei der Verwendung der Schnittstelle hilft, die Kosten senken, da sie die Verwendung einer Schnittstelle erleichtert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X