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?

1voto

dSerk Punkte 63

Erstellen Sie eine Liste der Dinge, die Ihre Objekte debe sein, haben oder tun und die Dinge, die Ihre Objekte puede (oder könnte ) sein, haben oder tun. Muss gibt Ihre Basistypen an und puede zeigt Ihre Schnittstellen an.

Z.B. Ihre PetBase debe Atmen, und Ihr IPet könnte DoTricks.

Die Analyse Ihres Problembereichs hilft Ihnen, die genaue Hierarchiestruktur zu definieren.

1voto

Ravindra babu Punkte 45577

Wann sollte ich eine Schnittstelle und wann eine Basisklasse verwenden?

Sie sollten Interface verwenden, wenn

  1. Sie haben reine abstract Methoden und haben keine nicht-abstrakten Methoden
  2. Sie haben keine Standardimplementierung von non abstract Methoden (außer in Java 8, wo Schnittstellenmethoden eine Standardimplementierung bieten)
  3. Wenn Sie Java 8 verwenden, bietet die Schnittstelle jetzt eine Standardimplementierung für einige nicht-abstrakte Methoden. Dies macht interface besser nutzbar im Vergleich zu abstract Klassen.

Werfen Sie einen Blick auf diese SE Frage für weitere Einzelheiten.

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

Ja, es ist besser und sauberer. Selbst wenn Sie eine Basisklasse mit einigen abstrakten Methoden haben, lassen Sie die Basisklasse erweitert abstract Methoden über die Schnittstelle. Sie können die Schnittstelle in Zukunft ändern, ohne die Basisklasse zu ändern.

Beispiel in java:

abstract class PetBase implements IPet {
// Add all abstract methods in IPet interface and keep base class clean. 
   Base class will contain only non abstract methods and static methods.
}

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.

Ich ziehe es vor, dass die Basisklasse die Schnittstelle implementiert.

 abstract class PetBase implements IPet {
 // Add all abstract methods in IPet
 }

 /*If ISheds,IBarks is common for Pets, your PetBase can implement ISheds,IBarks. 
  Respective implementations of PetBase can change the behaviour in their concrete classes*/

 abstract class PetBase implements IPet,ISheds,IBarks {
 // Add all abstract methods in respective interfaces
 }

Vorteile:

  1. Wenn ich eine weitere abstrakte Methode in bestehende Schnittstellen einfügen möchte, ändere ich einfach die Schnittstelle, ohne die abstrakte Basisklasse zu berühren. Wenn ich den Vertrag ändern möchte, ändere ich die Schnittstelle und die Implementierungsklassen, ohne die Basisklasse zu berühren.

  2. Sie können der Basisklasse über die Schnittstelle Unveränderlichkeit verleihen. Schauen Sie sich dies an Artikel

Weitere Einzelheiten finden Sie in dieser verwandten SE-Frage:

Wie hätte ich den Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse erklären sollen?

0voto

Mark Cidade Punkte 95914

Sie sollten eine Basisklasse verwenden, wenn es wirklich keinen Grund für andere Entwickler gibt, ihre eigene Basisklasse zusätzlich zu den Mitgliedern Ihres Typs verwenden zu wollen et Sie sehen Probleme bei der Versionierung voraus (siehe http://haacked.com/archive/2008/02/21/versioning-issues-with-abstract-base-classes-and-interfaces.aspx ).

Wenn die vererbenden Entwickler einen Grund haben, ihre eigene Basisklasse zu verwenden, um die Schnittstelle Ihres Typs zu implementieren, und Sie nicht sehen, dass sich die Schnittstelle ändert, dann sollten Sie eine Schnittstelle verwenden. In diesem Fall können Sie der Einfachheit halber immer noch eine Standard-Basisklasse einfügen, die die Schnittstelle implementiert.

0voto

Keithius Punkte 1139

Die Vererbung hat auch noch andere Vorteile, wie z. B. die Möglichkeit, dass eine Variable ein Objekt der Elternklasse oder der geerbten Klasse enthalten kann (ohne dass sie als etwas Generisches wie "Object" deklariert werden muss).

In .NET WinForms zum Beispiel leiten sich die meisten UI-Komponenten von System.Windows.Forms.Control ab, so dass eine so deklarierte Variable so ziemlich jedes UI-Element "enthalten" kann - sei es eine Schaltfläche, eine ListView oder was auch immer. Zugegeben, Sie haben dann keinen Zugriff auf alle Eigenschaften oder Methoden des Elements, aber Sie haben alle grundlegenden Funktionen - und das kann nützlich sein.

0 Stimmen

Ihr Beispiel unterstützt das Konzept nicht. Man kann das Gleiche mit einer Schnittstelle machen. Man muss dafür nicht nur eine Basisklasse haben.

0voto

Mark Punkte 409

Schnittstellen haben den eindeutigen Vorteil, dass sie in gewisser Weise "hot swappable" für Klassen sind. Der Wechsel einer Klasse von einem Elternteil zu einem anderen ist oft mit viel Arbeit verbunden, aber Schnittstellen können oft ohne große Auswirkungen auf die Implementierungsklasse entfernt und geändert werden. Dies ist vor allem dann nützlich, wenn Sie mehrere enge Verhaltensweisen haben, die eine Klasse "vielleicht" implementieren soll.

Das funktioniert besonders gut in meinem Bereich: der Spieleprogrammierung. Basisklassen können mit Tonnen von Verhaltensweisen aufgebläht werden, die von geerbten Objekten benötigt werden könnten. Mit Schnittstellen können verschiedene Verhaltensweisen zu Objekten einfach und schnell hinzugefügt oder entfernt werden. Wenn ich z. B. eine Schnittstelle für "IDamageEffects" für Objekte erstelle, die Schaden reflektieren sollen, kann ich diese leicht auf verschiedene Spielobjekte anwenden und meine Meinung später leicht ändern. Angenommen, ich entwerfe eine erste Klasse, die ich für "statische" dekorative Objekte verwenden möchte, und entscheide zunächst, dass sie nicht zerstörbar sind. Später entscheide ich vielleicht, dass es mehr Spaß machen würde, wenn sie explodieren könnten, also ändere ich die Klasse, um die Schnittstelle "IDamageEffects" zu implementieren. Das ist viel einfacher, als die Basisklassen zu wechseln oder eine neue Objekthierarchie zu erstellen.

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