Warum sind Schnittstellen bevorzugt abstrakte Klassen?
Ich nahm vor kurzem an ein Gespräch und Sie bat mich, die Frage "Warum sind Schnittstellen bevorzugt über Abstrakte Klassen?"
Ich habe versucht, ein paar Antworten wie:
- Wir können nur eine Erweitert die Funktionalität
- Sie sind zu 100% Abstrakt
- Umsetzung ist nicht hart codiert
Fragten Sie mich, nehmen Sie eine der JDBC-api, die Sie verwenden. "Warum sind Sie Schnittstellen?".
Bekomme ich eine bessere Antwort dafür?
- Ich bin mir fast sicher, ich habe gesehen die Frage, wie dies vor, aber nicht einmal Google finden können. Vielleicht ist mein Geist spielen tricks auf mich wieder.
- Hinweis: bearbeitete ich den Titel für das Lehramt an Gymnasien; ich verließ den Körper, da es zu sein scheint, Zitate, und vielleicht Taten Sie es sagen mögen.
- Dies ist eine Fangfrage, da nimmt es eine position zu dem Thema und gibt keinen Kontext, in dem es "kann" gelten. Ich Stimme mit devinb auf diese ein. Sie sind beide tools - verwenden Sie diese entsprechend. Zu viele Antworten hier rechtfertigen die Frage...das kann akzeptabel sein, wenn Sie wirklich wollen den job.
- Rechtfertigen Sie sich nicht die Frage mit einer Antwort. Das ist nicht das, was Sie sind (naja, sollte) suchen. Zeigen Sie, dass Sie wissen, was Sie reden, und den job tun können. Wenn Sie es sich lohnt zu arbeiten, Sie sind nicht auf der Suche nach einem Papagei.
- Siehe mein vollständiger Kommentar unten .. aber immer wenn ich eine Antwort bekommen wie du, der Kandidat bekommt ein eiskaltes "Dankeschön-für-Ihre-Zeit". Die Antwort zeigt keine Tiefe des Verstehens.
- Starten schreiben von testcases oder gehen die TDD-route, und Sie werden feststellen, dass das schreiben von testcases, ist weitaus einfacher, wenn die Verwendung von Schnittstellen. Es ermöglicht Ihnen, zu verspotten alles, was Sie nicht brauchen testcase.
- mögliche Duplikate von > Interface vs Abstrakte Klasse (allgemein OO)
- Möglich, Duplikat der Wann verwendet man ein interface statt einer abstrakten Klasse und Umgekehrt?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dass die interview-Frage spiegelt einen bestimmten glauben der person, die Frage zu stellen. Ich glaube, dass die person, die falsch ist, und daher können Sie gehen, eine der beiden Richtungen.
Die Antwort, die Sie wollen, nun, die anderen Poster haben hervorgehoben, diese unglaublich gut.
Mehrere interface-Vererbung die Vererbung der Kräfte der Klasse, damit die Implementierung Entscheidungen, Schnittstellen geändert werden können, einfacher.
Jedoch, wenn Sie eine überzeugende (und korrekte) argument in Ihrer Uneinigkeit, dann der interviewer könnte zur Kenntnis nehmen.
First, markieren Sie die positiven Dinge über Schnittstellen, ist dies ein MUSS.
Zweitens, ich würde sagen, die interfaces sind besser in vielen Szenarien, aber Sie führen auch zu code-Duplizierung, das ist eine negative Sache. Wenn Sie eine Breite Reihe von Unterklassen, die tun werden, sind weitgehend die gleichen Umsetzung, plus zusätzliche Funktionalität, dann möchten Sie vielleicht eine abstrakte Klasse. Es ermöglicht Ihnen, die haben viele ähnliche Objekte mit feinkörnigen detail, in der Erwägung, dass mit nur Schnittstellen, müssen Sie haben viele verschiedene Objekte mit fast den doppelten code.
Schnittstellen für viele Zwecke verwendet, und es gibt einen zwingenden Grund zu glauben, dass Sie 'besser'. Allerdings sollten Sie immer mit dem richtigen Werkzeug für den job, und das bedeutet, dass Sie nicht schreiben können aus abstrakten Klassen.
Im Allgemeinen, und dies ist keineswegs eine "Regel", die blind befolgt werden, die flexible Anordnung ist:
Die Schnittstelle gibt es für eine Reihe von Gründen:
Dies bedeutet, dass Sie ergreifen können, bereits bestehenden Klassen (oder Klassen erweitern MÜSSEN aus etwas anderem) und Sie arbeiten mit Ihrem code.
Der abstrakten Klasse ist es auf alle gängigen bits für die konkreten Klassen. Die abstrakte Klasse erweitert aus, wenn Sie mit dem schreiben neuer Klassen oder ändern von Klassen, die Sie möchten, es zu verlängern (vorausgesetzt, Sie erweitern von java.lang.Objekt).
Sollte man immer (es sei denn, Sie haben einen wirklich guten Grund, nicht zu) deklarieren Sie Variablen (instance, class, lokale, und die Parameter der Methode) als Schnittstelle.
Erhalten Sie nur ein Schuss auf die Vererbung. Wenn Sie machen eine abstrakte Klasse statt interface, jemand, der erbt Ihre Klasse nicht Erben auch eine andere abstrakte Klasse.
Implementieren Sie können mehr als eine Schnittstelle, aber Sie können nur Erben von einer einzigen Klasse
Abstrakte Klassen
1.Kann nicht instanziiert werden, unabhängig von deren abgeleiteten Klassen. Von abstrakten Klassen Konstruktoren werden aufgerufen, nur von Ihr abgeleiteten Klassen.
2.Definieren abstrakte member Signaturen, die Basis-Klassen implementieren müssen.
3.Mehr erweiterbare als Schnittstellen, ohne zu brechen keine version Kompatibilität. Mit abstrakten Klassen ist es möglich, fügen Sie zusätzliche nonabstract Mitglieder, die alle abgeleiteten Klassen Erben kann.
4.Können Daten in Feldern gespeichert.
5.Ermöglichen (virtuelle) Mitglieder, die Umsetzung und stellen daher eine default-Implementierung eines Mitglieds nicht an die abgeleitete Klasse.
6.Das ableiten von einer abstrakten Klasse verwendet eine Unterklasse ist die eine und einzige Basis-Klasse-option.
Schnittstelle
1.Kann nicht instanziiert werden.
2.Umsetzung aller Mitglieder der Schnittstelle erfolgt in der Basis-Klasse. Es ist nicht möglich zu implementieren, nur einige Mitglieder innerhalb der implementierenden Klasse.
3.Erweiterung der Schnittstellen mit den weiteren Mitgliedern der bricht die version Kompatibilität.
4.Kann nicht speichern Sie alle Daten. Felder können nur angegeben werden, auf die abgeleitete Klassen. Die Abhilfe für dieses ist, um Eigenschaften zu definieren, aber ohne Umsetzung.
5.Alle Mitglieder sind automatisch virtuelle und nicht eine beliebige Implementierung.
6.Obwohl keine default-Implementierung kann erscheinen, Klassen, Implementierung von Schnittstellen können weiterhin leiten sich von den anderen.
Als devinb und andere erwähnen, es klingt wie der interviewer zeigt Ihre Unwissenheit, nicht die Annahme Ihrer gültigen Antworten.
Jedoch die Erwähnung von JDBC könnte ein Hinweis darauf sein. In diesem Fall, vielleicht sind Sie Fragen, für die Vorteile eines client Codierung gegen eine Schnittstelle statt einer Klasse.
Also statt des absolut gültigen Antworten wie "man bekommt nur eine Verwendung der Vererbung", die im Zusammenhang mit der Klasse design, können Sie eine Antwort suchen mehr wie "entkoppelt ein client von einem konkreten Umsetzung".
Abstrakte Klassen haben eine Anzahl von möglichen Fallstricke. Zum Beispiel, wenn Sie eine Methode überschreiben, die
super()
Methode wird nicht aufgerufen, es sei denn, Sie explizit zu nennen. Dies kann Probleme verursachen, für schlecht umgesetzt übergeordneten Klassen. Auch, es gibt potenzielle Probleme mitequals()
wenn Sie die Vererbung verwenden.Mithilfe von Schnittstellen können die Verwendung der Zusammensetzung, wenn Sie wollen, gemeinsam eine Umsetzung. Zusammensetzung ist sehr Häufig eine bessere Möglichkeit zur Wiederverwendung von anderen Objekten, wie es ist weniger spröde. Vererbung ist einfach übernutzt oder für die falschen Zwecke eingesetzt.
Definition eine Schnittstelle ist eine sehr sichere Art und Weise zu definieren, wie ein Objekt Verhalten soll, ohne zu riskieren, die Sprödigkeit, die kann kommen mit eine andere Klasse erweitert, Abstrakt oder nicht.
Auch, wie Sie erwähnen, können Sie nur erweitern, eine Klasse zu einem Zeitpunkt, aber Sie implementieren können, so viele Schnittstellen, wie Sie es wünschen.
Abstrakte Klassen werden benutzt, wenn Sie Erben Umsetzung, Schnittstellen werden verwendet, wenn Sie Erben Spezifikation. Die JDBC-standards Stand, dass "Eine Verbindung muss diese". Das ist die Spezifikation.
Wenn Sie abstrakte Klassen, die Sie erstellen eine Verbindung zwischen der Unterklasse und Basisklasse. Diese Kopplung kann manchmal den code wirklich schwer zu verändern, zumal die Anzahl der Unterklassen erhöht. Schnittstellen dieses problem nicht haben.
Du auch nur ein Erbe, so stellen Sie sicher, dass Sie es für den richtigen Gründen.
Die anderen Beiträge haben einen tollen job gemacht, der Blick auf die Unterschiede zwischen interfaces und abstrakten Klassen, so dass ich nicht duplizieren diese Gedanken.
Aber ein Blick auf die interview-Frage, die bessere Frage ist wirklich "Wenn sollten Schnittstellen bevorzugt werden, die über abstrakte Klassen?" (und Umgekehrt).
Als mit den meisten Programmier-Konstrukte, Sie sind verfügbar für eine Vernunft und absoluten Aussagen wie in dem interview-Frage tendenziell zu verpassen. Es Art von erinnert mich an all die Anweisung, die Sie verwendet, um Lesen Sie über die springen - Anweisung in C. "verwenden Sie niemals springen - es zeigt schlechte coding-Fähigkeiten zu verbessern." Allerdings springen hatte immer seine entsprechenden Anwendungen.
Respektvoll nicht einverstanden mit den meisten der oben genannten Poster (tut mir Leid! mod mir nach unten, wenn Sie wollen 🙂 )
Erste, der "nur ein super-Klasse" zu beantworten ist lahm. Wer gab mir diese Antwort in einem interview, wäre schnell gekontert mit "C++ existierte vor Java und C++ hatte mehrere super Klassen. Warum denken Sie, dass James Gosling darf nur eine Superklasse für Java?"
Verstehen, die Philosophie hinter Ihrer Antwort, sonst sind Sie toast (zumindest, wenn ich Sie interviewen.)
Sekunde, Schnittstellen haben mehrere Vorteile gegenüber abstrakten Klassen, vor allem bei der Gestaltung von Oberflächen. Die größte ist, nicht mit einer bestimmten Klasse Struktur, die von dem Aufrufer einer Methode. Es gibt nichts Schlimmeres, als zu versuchen, verwenden Sie eine Methode aufrufen, die Forderungen einer bestimmten Klasse Struktur. Es ist schmerzhaft und unangenehm. Über eine Schnittstelle alles übergeben werden kann, um die Methode mit einem minimum an Erwartungen.
Beispiel:
vs.
Für die ehemaligen, wird dem Anrufer immer mit der vorhandenen Datenstruktur und schlug es in eine neue Hashtable.
Dritte, Schnittstellen erlauben eine public-Methoden in der konkreten Klasse die Praktiker zu werden "private". Wenn die Methode nicht in der Schnittstelle deklariert die Methode kann nicht verwendet werden (oder missbraucht), die von Klassen, die kein Gewerbe haben mit der Methode. Das bringt mich zu Punkt 4....
Vierten, Schnittstellen stellen eine minimale Vertrag zwischen der implementierenden Klasse und der Anrufer. Dieser minimal-Vertrag legt genau wie die konkrete Durchführung erwartet verwendet zu werden, und nicht mehr. Die aufrufende Klasse ist nicht erlaubt die Verwendung einer anderen Methode nicht angegeben ist, die durch den "Vertrag" von der Schnittstelle. Der interface-name in Gebrauch auch Aromen die Entwickler die Erwartung, wie Sie sein sollten mit dem Objekt. Wenn ein Entwickler übergeben wird ein
Der Entwickler weiß, dass die einzige Methode, die Sie aufrufen können, ist der Besuch Methode. Sie nicht bekommen, abgelenkt durch die glänzende Methoden in der konkreten Klasse, dass Sie nicht Durcheinander mit.
Schließlich, abstrakte Klassen haben viele Methoden, die sind wirklich nur für die Unterklassen verwendet werden. Also abstrakte Klassen neigen dazu, schauen ein wenig wie ein Chaos nach außen Entwickler, es gibt keine Hinweise, welche Methoden eingesetzt werden sollen, die von außen code.
Ja natürlich werden einige solcher Verfahren gemacht werden können, geschützt. Leider protected-Methoden sind auch sichtbar für andere Klassen im gleichen Paket. Und wenn eine abstrakte Klasse' Methode, die eine Schnittstelle implementiert, die Methode muss öffentlich sein.
Jedoch unter Verwendung der Schnittstellen, die alle diese Innereien hängen heraus, wenn man auf die abstrakte super-Klasse oder konkrete Klasse sind sicher verstaut.
Ja, ich weiß, dass natürlich auch die Entwickler können verwenden einige "spezielle" Kenntnisse zum umwandeln eines Objekts in ein anderes breiteres interface oder die konkrete Klasse selbst. Aber solch eine Besetzung gegen den erwarteten Vertrag, und die Entwickler sollten schlug mit einem Lachs.
Wenn Sie denken, dass X besser ist als Y, ich wäre nicht besorgt über den job bekommen, ich möchte nicht für jemanden zu arbeiten, der mich gezwungen, einen Entwurf über eine andere, weil Sie gesagt-Schnittstellen sind die besten. Beide sind gut, je nach situation, warum sonst haben die Sprache wählen Sie zum hinzufügen von abstrakten Klassen? Sicherlich, die Sprache, die Designer sind klüger als ich.
Dies ist das Problem der "Mehrfach-Vererbung".
Wir können "erweitert" nicht mehr als ein abstarct Klasse in einer Zeit, die durch eine andere Klasse, aber in Schnittstellen, können wir mit "implementieren" mehrere Schnittstellen in einer Klasse.
So, obwohl Java keine Mehrfachvererbung im Allgemeinen aber durch die Verwendung von Schnittstellen können wir integrieren multiplt erbschaft-Eigenschaft in ihm.
Hoffe, das hilft!!!
interface
s sind eine sauberere Art und Weise des Schreibens eine rein abstrakte Klasse. Man kann sagen, dass die Umsetzung nicht eingeschlichen (natürlich möchten Sie vielleicht zu tun, dass bestimmte Wartungs-Stadien, was macht die Schnittstellen schlecht). Das ist über es. Es ist fast kein Unterschied erkennbar zu dem der client-code.JDBC ist ein wirklich schlechtes Beispiel. Wer Fragen hat versucht zu implementieren, die Schnittstellen und pflegen Sie den code zwischen JDK-Versionen. JAX-WS ist noch schlimmer, hinzufügen von Methoden in update-Versionen.
Gibt es technische Unterschiede, wie die Fähigkeit, sich zu vermehren "Erben" - Schnittstelle. Das ist eher das Ergebnis von design verwirrt. In seltenen Fällen kann es nützlich sein, um eine Implementierung Hierarchie unterscheidet sich von der interface-Hierarchie.
Auf dem Nachteil für die Schnittstellen, der compiler ist nicht in der Lage zu Holen auf etwas unmöglich wirft/
instanceof
s.Es ist ein Grund, nicht erwähnt von den oben genannten.
Können Sie schmücken jede Schnittstelle einfach mit java.lang.reflektieren.Proxy-erlaubt Ihnen das hinzufügen von benutzerdefiniertem code zur Laufzeit, um jede Methode in der Schnittstelle gegeben. Es ist sehr mächtig.
Sehen http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html für ein tutorial.
Schnittstelle ist kein Ersatz für abstrakte Klasse.
Lieber
Schnittstelle: Zur Durchführung eines Vertrages, durch mehrere nicht zusammenhängende Objekte
abstrakte Klasse: Zu implementieren, die die gleichen oder unterschiedliche Verhalten bei mehreren verbundenen Objekte
Siehe zu diesem Zusammenhang SE Frage für die Anwendungsfälle der beiden Schnittstelle und abstrakte Klasse
Interface vs Abstrakte Klasse (allgemein OO)
Anwendungsfall:
Wenn Sie Template_method Muster, die Sie nicht erreichen können mit dem interface. Abstrakte Klasse gewählt werden sollte, um es zu erreichen.
Wenn Sie implementieren eine Funktion, die für viele unrleated Objekte, abstrakte Klasse und nicht dem Zweck dienen, und Sie haben zu wählen, Schnittstelle.
Können Sie mehrere interfaces implementieren, aber vor allem mit c# kann man nicht mehrere Erbschaften
Weil Schnittstellen nicht zwingen Sie in eine Vererbungshierarchie.
Definieren Sie Schnittstellen, wenn Sie nur erfordern, dass einige Objekt, die Umsetzung bestimmter Methoden, aber Sie kümmern sich nicht um seine Abstammung. So jemand kann eine vorhandene Klasse erweitern, um eine Schnittstelle implementieren, ohne Auswirkungen auf die bisher bestehenden Verhalten der Klasse.
Deshalb JDBC ist es, auf alle Schnittstellen; Sie weiß nicht wirklich, welche Klassen verwendet werden, in einer JDBC-Implementierung, Sie müssen nur alle JDBC-Implementierung um das gleiche Verhalten zu erwarten. Intern werden die Oracle-JDBC-Treiber können sehr unterschiedlich sein, von der PostgreSQL-Treiber, aber das ist irrelevant für Sie. Kann man haben, um Erben von einer internen Klassen, die der Datenbank-Entwickler, die bereits hatte, während die anderen kann man komplett von Grund auf neu entwickelt, aber das ist nicht wichtig für Sie, solange Sie implementieren beide die gleichen Schnittstellen, so dass Sie kommunizieren können, mit dem einen oder anderen, ohne zu wissen, das Innenleben der entweder.
Gut, ich würde vorschlagen, die Frage selbst sollte sein umformuliert. Schnittstellen sind vor allem Verträge, die eine Klasse übernimmt, die Umsetzung dieses Auftrags selbst ist unterschiedlich. Eine abstrakte Klasse wird in der Regel enthalten einige Standard-Logik und deren Kind-Klassen wird etwas mehr Logik.
Ich würde sagen, dass die Beantwortung der Fragen stützt sich auf das Diamant-problem. Java verhindert die mehrfache Vererbung zu vermeiden. ( http://en.wikipedia.org/wiki/Diamond_problem ).
Meine Antwort auf diese konkrete Frage ist :
SONNE nicht wissen, wie Sie Sie umsetzen sollen oder was Sie bei der Umsetzung. Die Dienstleister/db-Anbieter, um Ihre Logik in der Umsetzung.
Den JDBC-design hat eine Beziehung mit der Brücke, die Muster, die sagt "Entkoppelt eine Abstraktion von Ihrer Implementierung, so dass die beiden unabhängig voneinander variieren können".
Das bedeutet, dass der JDBC-api-Schnittstellen-Hierarchie entfaltet werden kann, unabhängig von der Umsetzung Hierarchie, die eine jdbc-Anbieter zur Verfügung stellt oder verwendet.
Abstrakte Klassen bieten eine Möglichkeit, um eine Vorlage zu definieren Verhalten, wo der Benutzer plugins in die details.
Ein gutes Beispiel ist Java 6 ist SwingWorker. Es definiert ein framework zu tun, etwas in den hintergrund, dass der Benutzer zu definieren, doInBackground() für die eigentliche Aufgabe.
Erweiterte ich diese Klasse so, dass Sie automatisch erstellt ein popup-Statusanzeige. Ich überschrieb done(), die Kontrolle der Entsorgung dieses pop-up, aber dann einen neuen überschreiben Punkt, so dass der Benutzer wahlweise festlegen, was passiert, wenn der Fortschrittsbalken verschwindet.
Der Benutzer hat immer noch die Anforderung der für die Implementierung doInBackground(). Jedoch, Sie können auch follow-up-Verhalten, wie dem öffnen ein weiteres Fenster und zeigt eine JOptionPane mit den Ergebnissen, oder einfach gar nichts tun.
Verwendet werden:
Diese zeigt, wie eine abstrakte Klasse kann gut bieten einen Vorlagen-Betrieb, orthogonal auf das Konzept der Schnittstellen Definition eines API-Vertrages.
Dessen hängen Sie von Ihrer Anforderung und power in der Umsetzung, die viel wichtiger sind.
Du hast so viele Antworten auf diese Frage.
Was ich denke, über diese Frage ist, dass abstrakte Klasse ist die evolution, wenn API.
Sie definieren Ihre zukünftige Funktion definition in der abstrakten Klasse, aber Sie brauchen nicht alle Implementierung der Funktion in der main-Klasse, aber mit dem interface kannst du nicht dieses Ding.