Ich habe diese Frage durchgearbeitet. Gibt es eine Möglichkeit, Klassenvariablen in Java zu überschreiben? Der erste Kommentar mit 36 positiven Stimmen war:
Wenn Sie jemals eine sehen
protected static
, laufen Sie.
Kann jemand erklären, warum ein protected static
verpönt ist?
final
. Ein veränderbares statisches Feld, das von mehreren Klassen gemeinsam genutzt wird, gibt definitiv Anlass zur Sorge. Es ist wahrscheinlich, dass mehrere Klassen, die ein statisches Feld aktualisieren, nicht zuverlässig oder leicht zu verfolgen sind, insbesondere da das Vorhandensein eines geschützten Felds oder einer geschützten Methode impliziert, dass die Klasse durch Klassen in anderen Paketen erweitert werden soll, möglicherweise Klassen, die nicht unter der Kontrolle von stehen Autor der Klasse, die das geschützte Feld enthält.final
bedeutet nicht, dass das Feld unveränderlich ist. Sie können dieobject
Referenzvariable jederzeit ändernfinal
.Antworten:
Es ist eher eine stilistische Sache als ein direktes Problem. Es deutet darauf hin, dass Sie nicht richtig überlegt haben, was mit der Klasse los ist.
Überlegen Sie, was
static
bedeutet:Überlegen Sie, was
protected
bedeutet:Die beiden Bedeutungen schließen sich nicht gerade gegenseitig aus, sind aber ziemlich nahe beieinander.
Der einzige Fall, in dem ich sehen kann, wo Sie die beiden zusammen verwenden könnten, ist, wenn Sie eine abstrakte Klasse hatten, die erweitert werden sollte, und die erweiterte Klasse dann das Verhalten mithilfe der im Original definierten Konstanten ändern könnte. Diese Art der Anordnung würde jedoch höchstwahrscheinlich sehr chaotisch enden und auf eine Schwäche im Design der Klassen hinweisen.
In den meisten Fällen wäre es besser, die Konstanten als öffentlich zu haben, da dies nur alles sauberer macht und den Personen, die in Unterklassen unterteilt sind, mehr Flexibilität ermöglicht. Abgesehen von allem anderen ist in vielen Fällen die Komposition der Vererbung vorzuziehen, während abstrakte Klassen die Vererbung erzwingen.
Um ein Beispiel dafür zu sehen, wie dies Dinge zerstören könnte, und um zu veranschaulichen, was ich damit meine, dass die Variable keine unabhängige Existenz hat, versuchen Sie diesen Beispielcode:
Sie sehen die Ergebnisse:
Probieren Sie es selbst aus unter: https://ideone.com/KM8u8O
Die Klasse kann von ohne
Test2
Zugriff auf den Namen auf das statische Mitglied zugreifen, erbt jedoch keine eigene Kopie und erhält keine eigene Kopie. Es betrachtet genau dasselbe Objekt im Speicher.test
Test
quelle
Rectangle
) anpassen, um Breite / Höhe anzupassen, um sicherzustellen, dass die Gleichheit (fürSquare
) unerwünschte Ergebnisse liefert, wenn Sie jeden Supertyp durch eine Instanz seines Subtyps ersetzen.Es ist verpönt, weil es widersprüchlich ist.
Das Erstellen einer Variablen
protected
impliziert, dass sie innerhalb des Pakets verwendet oder innerhalb einer Unterklasse vererbt wird .Wenn Sie die Variable
static
erstellen, wird sie zu einem Mitglied der Klasse, wodurch die Absichten, sie zu erben , beseitigt werden . Dies lässt nur die Absicht, innerhalb eines Pakets verwendet zu werden , und wir habenpackage-private
dafür (kein Modifikator).Die einzige Situation , die ich diese nützlich finden könnte, wenn Sie eine Klasse wurden erklärt , die verwendet werden sollen , um die Anwendung zu starten (wie JavaFX ist
Application#launch
, und wollten nur in der Lage von einer Unterklasse Start sein. Wenn ja dabei darauf, das Verfahren auchfinal
auf Verstecken nicht zulassen . Dies ist jedoch nicht "die Norm" und wurde wahrscheinlich implementiert, um eine Erhöhung der Komplexität durch Hinzufügen einer neuen Methode zum Starten von Anwendungen zu verhindern.Informationen zu den Zugriffsebenen der einzelnen Modifikatoren finden Sie in den folgenden Abschnitten: Die Java-Lernprogramme - Steuern des Zugriffs auf Mitglieder einer Klasse
quelle
static
die Absichten, es zu erben, beseitigt würden . Weil meine Unterklasse in einem anderen Paket immer noch das Feld Super benötigt, umprotected
darauf zugreifen zu können, obwohl es das iststatic
.package-private
kann nicht helfenprotected static
. Aber es ist ein Code-Geruch, daher der " Run " -Teil. Zugriffsmodifikatoren und Vererbung sind zwei verschiedene Themen. Ja, Sie können von einer Superklasse aus nicht auf ein statisches Mitglied zugreifen, wenn dies der Fall istpackage-private
. Sie sollten sich jedoch nichtstatic
in erster Linie auf die Vererbung von Referenzfeldern verlassen . Es ist ein Zeichen für schlechtes Design. Sie werden feststellen, dass Versuche,static
Methoden zu überschreiben , keine Ergebnisse liefern. Dies ist ein klares Zeichen dafür, dass die Vererbung nicht klassenbasiert ist. Wenn Sie Zugang außerhalb der Klasse oder des Pakets benötigen, sollte es seinpublic
private static
Util-Funktionen, aber ich denke, jemand möchte meine Klasse verbessern oder anpassen, und diese Util-Funktionen bieten ihnen möglicherweise auch Komfort.public
ist möglicherweise nicht geeignet, da util-Methoden nicht für den Benutzer der Instanzen meiner Klasse bestimmt sind. Könnten Sie mir helfen, ein gutes Design zu finden, anstattprotected
? Vielen DankIch sehe keinen besonderen Grund, warum dies verpönt werden sollte. Es kann immer Alternativen geben, um dasselbe Verhalten zu erzielen, und es hängt von der tatsächlichen Architektur ab, ob diese Alternativen "besser" sind als eine geschützte statische Methode oder nicht. Ein Beispiel, bei dem eine geschützte statische Methode zumindest sinnvoll wäre, könnte das folgende sein:
(Bearbeitet, um in separate Pakete aufgeteilt zu werden, um die Verwendung
protected
klarer zu machen )Daraus abgeleitet:
Eine andere abgeleitete Klasse:
Der
protected static
Modifikator kann hier sicherlich gerechtfertigt werden:static
, da sie nicht von Instanzvariablen abhängen. Sie sind nicht direkt an, wie eine polymorphe Methode, sondern sind „Nützlichkeit“ Methoden , die bieten Standardbestimmungsgemäßer Verwendung Implementierungen , die Teil einer komplexeren Berechnung sind, und dienen als „Bausteine“ der tatsächlichen Umsetzung.public
, da sie ein Implementierungsdetail sind. Und sie können nicht sein,private
weil sie von den erweiterten Klassen aufgerufen werden sollten. Sie können auch keine "Standard" -Sichtbarkeit haben, da sie dann für die erweiterten Klassen in anderen Paketen nicht zugänglich sind.(BEARBEITEN: Man könnte annehmen, dass sich der ursprüngliche Kommentar nur auf Felder und nicht auf Methoden bezog - dann war er jedoch zu allgemein)
quelle
protected final
(da Sie nicht möchten, dass sie überschrieben werden) und nicht als definierenstatic
. Die Tatsache, dass eine Methode keine Instanzvariablen verwendet, bedeutet nicht, dass dies der Fall sein solltestatic
(obwohl dies möglich ist ).final
, nicht nur nicht klar machen , dass das Verfahren nicht außer Kraft gesetzt werden soll, ist es zusätzlich macht den Leser klar , dass das Verfahren nicht Instanzvariablen nicht verwendet. So prägnant: Es gibt einfach keinen Grund, es nicht statisch zu machen.protected
, nicht um Vererbung zu zeigen, sondern um es unter einem einzigen Paket zu halten - nicht ausgesetzt. Ich denke, versiegelte Schnittstellen würden auf diese Weise hilfreich sein, wenn sie in Javaprotected
Paketen kann ohne Modifikator erreicht werden, während "Klassen erben (auch in verschiedenen Paketen)" bedeutet ...Statische Mitglieder werden nicht vererbt, und geschützte Mitglieder sind nur für Unterklassen (und natürlich für die enthaltende Klasse) sichtbar. Daher
protected static
hat a die gleiche Sichtbarkeit wiestatic
, was auf ein Missverständnis des Codierers hindeutet.quelle
protected
sind nicht gleich. Wenn Sie nur sagenstatic
, ist das Feld nur für Unterklassen im selben Paket sichtbar.protected static
ermöglicht den Zugriff innerhalb des Pakets oder von einer Unterklasse aus . Wenn Sie eine Variable statisch machen, werden die Absichten der Unterklasse entfernt, und die einzige Absicht bleibt der Zugriff aus dem Paket heraus.Eigentlich ist daran nichts grundsätzlich Falsches
protected static
. Wenn Sie wirklich eine statische Variable oder Methode wünschen, die für das Paket und alle Unterklassen der deklarierenden Klasse sichtbar ist, machen Sie sieprotected static
.Einige Leute meiden es im Allgemeinen
protected
aus verschiedenen Gründen, sie zu verwenden, und andere denken, dass nicht endgültigestatic
Variablen auf jeden Fall vermieden werden sollten (ich persönlich sympathisiere bis zu einem gewissen Grad mit letzteren), also denke ich, dass die Kombination vonprotected
und für diejenigen,static
die schlecht aussehen, schlecht aussehen muss gehören zu beiden Gruppen.quelle
Geschützt wird verwendet, damit es in Unterklassen verwendet werden kann. Es gibt keine Logik beim Definieren einer geschützten Statik, wenn sie im Kontext konkreter Klassen verwendet wird, da Sie auf dieselbe Variable zugreifen können. Dies ist eine statische Methode. Der Complier gibt jedoch eine Warnung aus, um statisch auf die statische Variable der Superklasse zuzugreifen.
quelle
Nun, wie die meisten Leute geantwortet haben:
protected
bedeutet - ' paketprivat + Sichtbarkeit für Unterklassen - die Eigenschaft / das Verhalten ist VERERBT 'static
bedeutet - " das Gegenteil von Instanz - es ist eine CLASS-Eigenschaft / ein CLASS-Verhalten, dh es ist NICHT ERBT "Daher sind sie leicht widersprüchlich und inkompatibel.
Kürzlich bin ich jedoch auf einen Anwendungsfall gestoßen, bei dem es möglicherweise sinnvoll ist, diese beiden zusammen zu verwenden. Stellen Sie sich vor, Sie möchten eine
abstract
Klasse erstellen , die für unveränderliche Typen übergeordnet ist und eine Reihe von Eigenschaften aufweist, die den Untertypen gemeinsam sind. Um die Unveränderlichkeit richtig zu implementieren und die Lesbarkeit zu gewährleisten, kann das Builder- Muster verwendet werden.Und warum
protected static
? Weil ich einen nicht abstrakten Subtyp möchte,AbstactType
der seinen eigenen nicht abstrakten Builder implementiert und sich außerhalb befindetpackage X
, um auf den zugreifen und ihn wiederverwenden zu könnenBaseBuilder
.Natürlich können wir die
BaseBuilder
Öffentlichkeit machen, aber dann kommen wir zu anderen widersprüchlichen Aussagen:Also kombinieren wir in beiden Fällen mit
protected static
undpublic
Erbauer einesabstract class
widersprüchlichen Aussagen. Es ist eine Frage der persönlichen Vorlieben.Ich bevorzuge jedoch immer noch den
public
Erbauer eines,abstract class
weil sich dasprotected static
für mich in einer OOD- und OOP-Welt unnatürlicher anfühlt!quelle
Es ist nichts falsch daran zu haben
protected static
. Eine Sache, die viele Leute übersehen, ist, dass Sie möglicherweise Testfälle für statische Methoden schreiben möchten, die Sie unter normalen Umständen nicht verfügbar machen möchten. Ich habe festgestellt, dass dies besonders nützlich ist, um Tests für statische Methoden in Dienstprogrammklassen zu schreiben.quelle