Frage

Was sind gute Gründe Vererbung in Java, zum Beispiel zu verbieten, die von endgültigen Klassen oder Klassen unter Verwendung eines einzelnen, privaten parameterlos Konstruktor? Was sind gute Gründe, ein Verfahren endgültig zu machen?

War es hilfreich?

Lösung

Ihre beste Referenz ist hier Artikel 19 von Joshua Bloch ausgezeichneten Buch „Effective Java“, die so genannten „Entwurf und Dokument für die Vererbung oder aber es verbieten“. (Es ist Punkt 17 in der zweiten Auflage und Punkt 15 in der ersten Ausgabe.) Sie sollen es wirklich lesen, aber ich werde zusammenfassen.

Die Interaktion von geerbten Klassen mit ihren Eltern können überraschende und unvorhersehbare, wenn die Vorfahren nicht geerbt werden entworfen wurde.

Klassen sollten daher in zwei Arten kommen:

  1. Klassen entwickelt erweitert sein , und mit genug Dokumentation zu beschreiben, wie es getan werden sollte

  2. Klassen markiert letzte

Wenn Sie rein interne Code schreiben kann dies ein bisschen zu viel des Guten. Doch der zusätzliche Aufwand in dem Hinzufügen fünf Zeichen zu einer Klassendatei beteiligt ist sehr klein. Wenn Sie nur für die interne comsumption schreiben dann eine Zukunft Coder kann jederzeit wieder entfernen die ‚endgültige‘ -. Sie es als eine Warnung denken kann sagen: „diese Klasse nicht mit Vererbung konzipiert wurde“

Andere Tipps

Sie möchten vielleicht eine Methode final machen, so dass zwingende Klassen nicht Verhalten ändern können, die in anderen Verfahren gerechnet wird. Methoden in der Konstrukteurs genannt werden oft final deklarieren, so dass Sie keine unangenehmen Überraschungen, wenn Objekte zu schaffen.

Ein Grund eine Klasse final zu machen wäre, wenn Sie Komposition der Vererbung erzwingen wollte. Dies ist im allgemeinen wünschenswert, bei der Vermeidung enge Kopplung zwischen den Klassen.

Es gibt drei Anwendungsfälle, wo man für die endgültigen Methoden gehen.

  1. Um abgeleitete Klasse zu vermeiden von einer bestimmten Basisklasse Funktionalität überschreiben.
  2. Dies ist für die Sicherheit Zweck, wo Basisklasse einige wichtige Kernfunktionalität des Rahmens geben, wo abgeleiteten Klasse nicht angenommen wird, es zu ändern.
  3. sind abschließende Methoden schneller als Instanzmethoden, da es keine Verwendung von virtuellem Tischkonzept für die endgültigen und private Methoden ist. Also, wo immer es gibt eine Möglichkeit, versuchen endgültige Methoden zu verwenden.

Zweck zur Herstellung einer Klasse final:

Damit kein Körper kann diese Klassen erweitern und ihr Verhalten ändern.

Zum Beispiel: Wrapper-Klasse Integer ist eine endgültige Klasse. Wenn diese Klasse nicht endgültig ist, dann kann jeder einer Integer in seine eigene Klasse erweitern und das grundlegende Verhalten von Integer-Klasse ändern. Um dies zu vermeiden, java alle Wrapper-Klassen als final Klassen gemacht.

Sie möchten vielleicht unveränderliche Objekte machen ( http://en.wikipedia.org/wiki/Immutable_object ), möchten Sie vielleicht einen Singleton ( http://en.wikipedia.org/wiki/ erstellen Singleton_pattern ), oder Sie können aus Gründen der Effizienz, Sicherheit oder die Sicherheit von Überschreiben der Methode, jemanden verhindern wollen.

Die Vererbung ist wie eine Kettensäge - sehr mächtig, aber schrecklich in die falschen Hände gerät. Entweder entwerfen Sie eine Klasse von vererbt werden (die Flexibilität einschränken und viel länger dauern) oder man sollte es verbieten.

Siehe Effective Java 2. Auflage Artikel 16 und 17, oder in meinem Blogbeitrag “ Erbschaftssteuer ".

Hmmm ... Ich kann von zwei Dinge denken:

Sie können eine Klasse, die mit bestimmten Sicherheitsfragen befasst. Durch Subklassen es und Ihr System der Unterklasse Version davon Fütterung kann ein Angreifer Sicherheitsbeschränkungen umgehen. Z.B. Ihre Anwendung könnte Plugins unterstützen und wenn ein Plugin nur Ihre sicherheitsrelevanten Klassen Subklassen kann, kann sie diesen Trick irgendwie eine Unterklasse Version davon an ihren Platz schmuggeln verwenden. Dies ist jedoch eher etwas Sonne mit Bezug auf Applets zu tun hat, und dergleichen, vielleicht nicht so ein realistischen Fall.

Ein viel realistischer ist ein Objekt wird wandelbar zu vermeiden. Z.B. da Strings unveränderlich sind, können Sie Ihren Code sicher Verweise auf sie halten

 String blah = someOtherString;

anstelle der Zeichenfolge zuerst zu kopieren. Wenn Sie jedoch können String Unterklasse, können Sie Methoden, um es hinzuzufügen, dass der String-Wert ermöglichen, modifiziert werden, jetzt kann kein Code vertrauen mehr, dass die Zeichenfolge gleich bleiben wird, wenn es nur kopiert die Zeichenfolge wie oben, statt es duplizieren muss die String.

Menschen daran zu hindern, Dinge zu tun, die sich selbst und andere verwirren könnten. Stellen Sie sich eine Physik-Bibliothek, wo Sie einige Konstanten definiert oder Berechnungen haben. Ohne das letzte Schlüsselwort, könnte jemand kommen und einfache Berechnungen oder Konstanten definieren, die sich niemals ändern sollte.

Auch wenn Sie eine kommerzielle Closed-Source-Klasse schreiben, könnten Sie nicht wollen die Menschen auf der ganzen Linie die Funktionalität ändern zu können, vor allem, wenn u Unterstützung dafür geben müssen und die Menschen haben Ihre Methode überschrieben und klagen darüber, dass es gibt unerwartete Ergebnisse aufrufen.

Wenn Sie Klassen und Methoden als Endnote, können Sie eine kleine Leistungssteigerung feststellen, da die Laufzeit nicht die richtige Klassenmethode suchen hat für ein bestimmtes Objekt aufzurufen. Nicht endgültige Methoden werden als virtuelle markiert, so dass sie richtig, wenn nötig, können endgültige Methoden direkt verknüpft werden erweitert werden kann oder inline in der Klasse erstellt.

Sie möchten ein Verfahren endgültig machen, so dass zwingende Klassen nicht sein Verhalten nicht ändert. Wenn Sie die Methode public in der Lage sein wollen, machen das Verhalten zu ändern. Wenn Sie eine öffentliche Methode außer Kraft setzen kann geändert werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top