Mir wurde eine Frage gestellt, ich wollte meine Antwort hier überprüfen lassen.
F: In welchem Szenario ist es besser, eine abstrakte Klasse zu erweitern, als die Schnittstelle (n) zu implementieren?
A: Wenn wir ein Entwurfsmuster für die Vorlagenmethode verwenden.
Hab ich recht ?
Es tut mir leid, wenn ich die Frage nicht klar formulieren konnte.
Ich kenne den grundlegenden Unterschied zwischen abstrakter Klasse und Schnittstelle.
1) Verwenden Sie eine abstrakte Klasse, wenn die Anforderung so ist, dass für jede bestimmte Operation dieselbe Funktionalität in jeder Unterklasse implementiert werden muss (implementieren Sie die Methode) und für einige andere Operationen unterschiedliche Funktionen (nur Methodensignaturen).
2) Verwenden Sie die Schnittstelle, wenn Sie die Signatur gleich (und die Implementierung unterschiedlich) setzen müssen, damit Sie die Schnittstellenimplementierung einhalten können
3) Wir können maximal eine abstrakte Klasse erweitern, aber mehr als eine Schnittstelle implementieren
Wiederholung der Frage: Gibt es außer den oben genannten noch andere Szenarien, in denen speziell die Verwendung einer abstrakten Klasse erforderlich ist (man sieht, dass das Entwurfsmuster der Vorlagenmethode nur konzeptionell darauf basiert)?
Interface vs. Abstract Klasse
Die Wahl zwischen diesen beiden hängt wirklich davon ab, was Sie tun möchten, aber zum Glück kann Erich Gamma uns ein bisschen helfen.
Wie immer gibt es einen Kompromiss, eine Schnittstelle gibt Ihnen Freiheit in Bezug auf die Basisklasse, eine abstrakte Klasse gibt Ihnen die Freiheit, später neue Methoden hinzuzufügen . - Erich Gamma
Sie können eine Benutzeroberfläche nicht ändern, ohne viele andere Dinge in Ihrem Code ändern zu müssen. Die einzige Möglichkeit, dies zu vermeiden, besteht darin, eine ganz neue Benutzeroberfläche zu erstellen, was möglicherweise nicht immer gut ist.
Abstract classes
sollte hauptsächlich für Objekte verwendet werden, die eng miteinander verbunden sind. Interfaces
sind besser darin, gemeinsame Funktionen für nicht verwandte Klassen bereitzustellen.
Antworten:
Wann werden Schnittstellen verwendet?
Eine Schnittstelle ermöglicht es jemandem, von vorne zu beginnen, um Ihre Schnittstelle zu implementieren oder Ihre Schnittstelle in einem anderen Code zu implementieren, dessen ursprünglicher oder primärer Zweck sich stark von Ihrer Schnittstelle unterschied. Für sie ist Ihre Benutzeroberfläche nur zufällig, etwas, das zu ihrem Code hinzugefügt werden muss, um Ihr Paket verwenden zu können. Der Nachteil ist, dass jede Methode in der Schnittstelle öffentlich sein muss. Möglicherweise möchten Sie nicht alles verfügbar machen.
Wann werden abstrakte Klassen verwendet?
Eine abstrakte Klasse bietet dagegen mehr Struktur. Es definiert normalerweise einige Standardimplementierungen und bietet einige Tools, die für eine vollständige Implementierung nützlich sind. Der Haken ist, dass Code, der ihn verwendet, Ihre Klasse als Basis verwenden muss. Dies kann sehr unpraktisch sein, wenn die anderen Programmierer, die Ihr Paket verwenden möchten, bereits unabhängig voneinander eine eigene Klassenhierarchie entwickelt haben. In Java kann eine Klasse nur von einer Basisklasse erben.
Wann man beide verwendet
Sie können das Beste aus beiden Welten anbieten, eine Schnittstelle und eine abstrakte Klasse. Implementierer können Ihre abstrakte Klasse ignorieren, wenn sie dies wünschen. Der einzige Nachteil dabei ist, dass das Aufrufen von Methoden über ihren Schnittstellennamen etwas langsamer ist als das Aufrufen von Methoden über ihren abstrakten Klassennamen.
quelle
If we are using template method design pattern
wir nicht sagenYES
oderNO
Ja, wenn Sie JAXB verwenden. Es mag keine Schnittstellen. Sie sollten entweder abstrakte Klassen verwenden oder diese Einschränkung mit Generika umgehen.
Von einer persönlichen Blog Post :
Schnittstelle:
Im Allgemeinen sollten Schnittstellen verwendet werden, um Verträge zu definieren (was erreicht werden soll, nicht wie erreicht werden soll).
Abstrakte Klasse:
Abstrakte Klassen sollten für die (teilweise) Implementierung verwendet werden. Sie können ein Mittel sein, um die Implementierung von API-Verträgen einzuschränken.
quelle
default
undstatic
auch Methoden.Die Schnittstelle wird verwendet, wenn Sie das Szenario haben, dass alle Klassen dieselbe Struktur haben, aber völlig unterschiedliche Funktionen haben.
Abstrakte Klasse wird verwendet, wenn Sie das Szenario haben, dass alle Klassen dieselbe Struktur haben, aber einige gleiche und einige unterschiedliche Funktionen.
Schauen Sie sich den Artikel an: http://shoaibmk.blogspot.com/2011/09/abstract-class-is-class-which-cannot-be.html
quelle
Hier gibt es viele gute Antworten, aber ich finde oft, dass die Verwendung von BEIDEN Schnittstellen und abstrakten Klassen der beste Weg ist. Betrachten Sie dieses erfundene Beispiel:
Sie sind Softwareentwickler bei einer Investmentbank und müssen ein System aufbauen, das Aufträge auf einem Markt platziert. Ihre Benutzeroberfläche erfasst die allgemeinste Vorstellung davon, was ein Handelssystem tut .
und kann in einer Schnittstelle erfasst werden,
ITradeSystem
Jetzt können Ingenieure, die am Verkaufsschalter und in anderen Geschäftsbereichen arbeiten, eine Schnittstelle zu Ihrem System herstellen, um ihren vorhandenen Apps Funktionen zur Auftragserteilung hinzuzufügen. Und du hast noch nicht einmal angefangen zu bauen! Dies ist die Stärke von Schnittstellen.
So Sie voran gehen und das System für Bau Aktienhändler; Sie haben gehört, dass Ihr System über eine Funktion verfügt, mit der Sie günstige Aktien finden können, und sind sehr gespannt darauf, diese auszuprobieren! Sie erfassen dieses Verhalten in einer Methode namens
findGoodDeals()
, erkennen aber auch, dass es eine Menge chaotischer Dinge gibt, die mit der Verbindung zu den Märkten verbunden sind. Sie können beispielsweise ein öffnen habenSocketChannel
,Die konkreten Implementierungen werden viele dieser chaotischen Methoden haben
connectToMarket()
, aber esfindGoodDeals()
ist alles , was die Händler wirklich interessieren.Hier kommen abstrakte Klassen ins Spiel. Ihr Chef informiert Sie, dass Devisenhändler auch Ihr System nutzen möchten. Wenn Sie sich die Devisenmärkte ansehen, sehen Sie, dass die Sanitärinstallationen fast identisch mit den Aktienmärkten sind. In der Tat
connectToMarket()
kann wörtlich wiederverwendet werden, um eine Verbindung zu Devisenmärkten herzustellen. InfindGoodDeals()
der Währungsbranche ist dies jedoch ein ganz anderes Konzept. Bevor Sie also die Codebasis an das Devisen-Zauberkind über den Ozean weitergeben, werden Sie zunächst in eineabstract
Klasse umgestaltet , ohne sie zufindGoodDeals()
beeinträchtigenIhr Aktienhandelssystem implementiert,
findGoodDeals()
wie Sie bereits definiert haben,Aber jetzt kann das FX Whiz Kid sein System aufbauen, indem es einfach eine Implementierung
findGoodDeals()
für Währungen bereitstellt . Sie muss weder Socket-Verbindungen noch die Schnittstellenmethoden neu implementieren!Das Programmieren auf eine Schnittstelle ist leistungsstark, aber ähnliche Anwendungen implementieren Methoden häufig auf nahezu identische Weise neu. Durch die Verwendung einer abstrakten Klasse werden Neuimplementierungen vermieden, während die Leistung der Schnittstelle erhalten bleibt.
Hinweis: Man kann sich fragen, warum dies
findGreatDeals()
nicht Teil der Benutzeroberfläche ist. Denken Sie daran, dass die Schnittstelle die allgemeinsten Komponenten eines Handelssystems definiert. Ein anderer Ingenieur kann ein VOLLSTÄNDIG VERSCHIEDENES Handelssystem entwickeln, bei dem es ihm egal ist, gute Geschäfte zu finden. Die Benutzeroberfläche garantiert, dass der Sales Desk auch eine Schnittstelle zu seinem System herstellen kann. Daher ist es vorzuziehen, Ihre Benutzeroberfläche nicht mit Anwendungskonzepten wie "Schnäppchen" zu verwickeln.quelle
Welche sollten Sie verwenden, abstrakte Klassen oder Schnittstellen?
Erwägen Sie die Verwendung abstrakter Klassen, wenn eine dieser Aussagen für Ihr Szenario gilt:
Sie möchten Code für mehrere eng verwandte Klassen freigeben.
Sie erwarten, dass Klassen, die Ihre abstrakte Klasse erweitern, viele gängige Methoden oder Felder haben oder andere Zugriffsmodifikatoren als öffentliche (wie geschützte und private) erfordern.
Sie möchten nicht statische oder nicht endgültige Felder deklarieren. Auf diese Weise können Sie Methoden definieren, die auf den Status des Objekts zugreifen und diesen ändern können, zu dem sie gehören.
Erwägen Sie die Verwendung von Schnittstellen, wenn eine dieser Aussagen auf Ihre Situation zutrifft:
Sie erwarten, dass nicht verwandte Klassen Ihre Schnittstelle implementieren. Beispielsweise werden die Schnittstellen Comparable und Cloneable von vielen nicht verwandten Klassen implementiert.
Sie möchten das Verhalten eines bestimmten Datentyps angeben, sind jedoch nicht darüber besorgt, wer sein Verhalten implementiert.
Sie möchten die Mehrfachvererbung des Typs nutzen.
http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
quelle
In den letzten drei Jahren haben sich die Dinge stark geändert, und es wurden neue Funktionen für die Schnittstelle zur Java 8-Version hinzugefügt.
Von der Oracle - Dokumentation Seite auf Schnittstelle:
Wie Sie in Ihrer Frage zitiert haben, eignet sich die abstrakte Klasse am besten für Muster von Vorlagenmethoden, bei denen Sie ein Skelett erstellen müssen. Die Schnittstelle kann hier nicht verwendet werden.
Eine weitere Überlegung, abstrakte Klasse der Schnittstelle vorzuziehen:
Sie haben keine Implementierung in der Basisklasse und nur Unterklassen müssen ihre eigene Implementierung definieren. Sie benötigen eine abstrakte Klasse anstelle einer Schnittstelle, da Sie den Status für Unterklassen freigeben möchten.
Abstrakte Klasse stellt fest, "ist eine" Beziehung zwischen verwandten Klassen und Schnittstelle bietet "hat eine" Fähigkeit zwischen nicht verwandten Klassen .
In Bezug auf den zweiten Teil Ihrer Frage, der für die meisten Programmiersprachen einschließlich Java vor der Veröffentlichung von Java-8 gültig ist
Wenn Sie es vorziehen, dass abstrakte Klassen früher mit den beiden oben genannten Überlegungen zusammenarbeiten, müssen Sie jetzt überdenken, da Standardmethoden den Schnittstellen leistungsstarke Funktionen hinzugefügt haben.
So wählen Sie eine von ihnen zwischen Interface und abstrakte Klasse, Oracle - Dokumentation Seite Zitat , dass:
Weitere Informationen finden Sie in diesen verwandten Fragen:
Interface vs Abstract Class (allgemeines OO)
Wie hätte ich den Unterschied zwischen einer Interface- und einer Abstract-Klasse erklären sollen?
Zusammenfassend: Das Gleichgewicht neigt sich jetzt mehr zu Schnittstellen .
Einige Entwurfsmuster verwenden abstrakte Klassen (über Schnittstellen), abgesehen vom Muster der Vorlagenmethode.
Schöpfungsmuster:
Abstract_factory_pattern
Strukturmuster:
Decorator_pattern
Verhaltensmuster:
Mediator_pattern
quelle
Du bist nicht richtig. Es gibt viele Szenarien. Es ist einfach nicht möglich, es auf eine einzige 8-Wort-Regel zu reduzieren.
quelle
Die kürzeste Antwort lautet: Erweitern Sie die abstrakte Klasse, wenn einige der von Ihnen gesuchten Funktionen bereits darin implementiert sind.
Wenn Sie die Schnittstelle implementieren, müssen Sie alle Methoden implementieren. Für abstrakte Klassen ist die Anzahl der Methoden, die Sie implementieren müssen, möglicherweise geringer.
Im Vorlagenentwurfsmuster muss ein Verhalten definiert sein. Dieses Verhalten hängt von anderen Methoden ab, die abstrakt sind. Indem Sie eine Unterklasse erstellen und diese Methoden definieren, definieren Sie tatsächlich das Hauptverhalten. Das zugrunde liegende Verhalten kann sich nicht in einer Schnittstelle befinden, da die Schnittstelle nichts definiert, sondern nur deklariert. Ein Template-Design-Muster enthält also immer eine abstrakte Klasse. Wenn Sie den Ablauf des Verhaltens beibehalten möchten, müssen Sie die abstrakte Klasse erweitern, das Hauptverhalten jedoch nicht überschreiben.
quelle
Pure virtual functions can also be used where the method declarations are being used to define an interface - similar to what the interface keyword in Java explicitly specifies. In such a use, derived classes will supply all implementations. In such a design pattern, the abstract class which serves as an interface will contain only pure virtual functions, but no data members or ordinary methods.
Teil (1/2)no data members or ordinary methods
[in abstrakter Klasse] erklärt.Meiner Meinung nach ist der grundlegende Unterschied der folgende
an interface can't contain non abstract methods while an abstract class can
. Wenn Unterklassen ein gemeinsames Verhalten haben, kann dieses Verhalten in der Superklasse implementiert und somit in die Unterklassen vererbt werdenAußerdem zitierte ich Folgendes aus dem Buch "Software Architecture Design ppatterns in Java"
"In der Programmiersprache Java wird die Mehrfachvererbung nicht unterstützt. Das bedeutet, dass eine Klasse nur von einer einzelnen Klasse erben kann. Daher sollte die Vererbung nur verwendet werden, wenn dies unbedingt erforderlich ist. Nach Möglichkeit sollten Methoden angegeben werden, die das gemeinsame Verhalten angeben Die Form einer Java-Schnittstelle, die von verschiedenen Implementiererklassen implementiert werden soll. Schnittstellen leiden jedoch unter der Einschränkung, dass sie keine Methodenimplementierungen bereitstellen können. Dies bedeutet, dass jeder Implementierer einer Schnittstelle alle in einer Schnittstelle deklarierten Methoden explizit implementieren muss, auch wenn einige davon Methoden stellen den unveränderlichen Teil der Funktionalität dar und haben in allen Implementiererklassen genau die gleiche Implementierung. Dies führt zu redundantem Code.Das folgende Beispiel zeigt, wie das Muster der abstrakten übergeordneten Klasse in solchen Fällen verwendet werden kann, ohne dass redundante Methodenimplementierungen erforderlich sind. "
quelle
Abstrakte Klassen unterscheiden sich von Schnittstellen in zwei wichtigen Aspekten
quelle
Dies ist eine gute Frage. Die beiden sind nicht ähnlich, können aber aus demselben Grund wie beim Umschreiben verwendet werden. Verwenden Sie beim Erstellen am besten die Schnittstelle. Wenn es um den Unterricht geht, ist es gut zum Debuggen.
quelle
Abstract classes should be extended when you want to some common behavior to get extended
. Die abstrakte Superklasse hat das gemeinsame Verhalten und definiert abstrakte Methoden / spezifisches Verhalten, die Unterklassen implementieren sollen.Interfaces allows you to change the implementation anytime allowing the interface to be intact
.quelle
Das ist mein Verständnis, hoffe das hilft
Abstrakte Klassen:
Schnittstellen:
quelle
Verwendung von Abstract und Interface:
Einer hat "Is-A-Relationship" und ein anderer hat "Has-A-Relationship"
Die Standardeigenschaften wurden abstrakt festgelegt, und zusätzliche Eigenschaften können über die Schnittstelle ausgedrückt werden.
Beispiel: -> Beim Menschen haben wir einige Standardeigenschaften, die Essen, Schlafen usw. sind. Wenn jedoch jemand andere Lehrplanaktivitäten wie Schwimmen, Spielen usw. hat, können diese durch die Schnittstelle ausgedrückt werden.
quelle