Ich habe mit Modifikatoren mit statischer Methode herumgespielt und bin auf ein seltsames Verhalten gestoßen.
Wie wir wissen, können statische Methoden nicht überschrieben werden, da sie eher der Klasse als der Instanz zugeordnet sind.
Wenn ich also das folgende Snippet habe, wird es gut kompiliert
//Snippet 1 - Compiles fine
public class A {
static void ts() {
}
}
class B extends A {
static void ts() {
}
}
Wenn ich jedoch den letzten Modifikator für die statische Methode in Klasse A einbinde, schlägt die Kompilierung fehl. Ts () in B kann ts () in A nicht überschreiben. überschriebene Methode ist statisch final .
Warum passiert dies, wenn die statische Methode überhaupt nicht überschrieben werden kann?
Antworten:
Statische Methoden können nicht überschrieben, aber ausgeblendet werden. Die
ts()
Methode von B überschreibt nicht diets()
von A (unterliegt keinem Polymorphismus), sondern verbirgt sie. Wenn Siets()
B anrufen (NICHTA.ts()
oderB.ts()
... nurts()
), wird der von B und nicht A aufgerufen. Da dies keinem Polymorphismus unterworfen ist, wird der Anrufts()
in A niemals zu dem in B umgeleitet.Das Schlüsselwort verhindert
final
, dass die Methode ausgeblendet wird. Sie können also nicht ausgeblendet werden, und ein Versuch dazu führt zu einem Compilerfehler.Hoffe das hilft.
quelle
A#ts
er vererbt wird und eine solche Methode bereits vorhanden istB
, einfach zwei Methoden mit derselben Signatur und einem anderen Modifikator (final
) nicht als Überladung funktionieren würden. Ich wünschte, ich könnte mir eine einfache Nachricht dafür vorstellenDas ist nicht genau richtig. Der Beispielcode bedeutet wirklich, dass die Methode ts in B die Methode ts in A verbirgt. Sie wird also nicht genau überschrieben. Drüben auf Javaranch gibt es eine schöne Erklärung.
quelle
Statische Methoden gehören zur Klasse, nicht zur Instanz.
A.ts()
undB.ts()
werden immer getrennte Methoden sein.Das eigentliche Problem ist, dass Sie mit Java statische Methoden für ein Instanzobjekt aufrufen können. Statische Methoden mit derselben Signatur aus der übergeordneten Klasse werden ausgeblendet, wenn sie von einer Instanz der Unterklasse aufgerufen werden. Sie können die endgültigen Methoden jedoch nicht überschreiben / ausblenden .
Sie würden denken, die Fehlermeldung würde das Wort versteckt anstelle von überschrieben verwenden ...
quelle
Möglicherweise sind Sie in der Lage, über eine endgültige statische Methode nachzudenken, wenn Sie Folgendes berücksichtigen:
Folgende Klassen haben:
Nun wäre die "richtige" Art, diese Methoden aufzurufen
Dies würde dazu führen,
AB
aber Sie könnten die Methoden auch für Instanzen aufrufen:was auch dazu führen würde
AB
.Betrachten Sie nun Folgendes:
das würde drucken
A
. Das könnte Sie überraschen, da Sie tatsächlich ein Klassenobjekt habenB
. Da Sie es jedoch von einer Referenz des Typs aus aufrufenA
, wird es aufgerufenA.ts()
. Sie könnenB
mit folgendem Code drucken :In beiden Fällen stammt das Objekt, das Sie haben, tatsächlich aus der Klasse
B
. Abhängig vom Zeiger, der auf das Objekt zeigt, rufen Sie die Methode vonA
oder von aufB
.Angenommen, Sie sind der Entwickler der Klasse
A
und möchten die Unterklassifizierung zulassen. Aber Sie möchten wirklich, dass die Methodets()
, wann immer sie aufgerufen wird, auch von einer Unterklasse, genau das tut, was Sie möchten, und nicht von einer Unterklassenversion ausgeblendet wird. Dann könnten Sie es schaffenfinal
und verhindern, dass es in der Unterklasse versteckt wird. Und Sie können sicher sein, dass der folgende Code die Methode aus Ihrer Klasse aufruftA
:Ok, zugegeben, das ist irgendwie konstruiert, aber es könnte in einigen Fällen Sinn machen.
Sie sollten keine statischen Methoden für Instanzen aufrufen, sondern direkt für die Klassen - dann haben Sie dieses Problem nicht. Auch IntelliJ IDEA zeigt Ihnen beispielsweise eine Warnung an, wenn Sie eine statische Methode für eine Instanz aufrufen und wenn Sie eine statische Methode endgültig machen.
quelle
Die ts () -Methode in B überschreibt nicht die ts () -Methode in A, sondern ist einfach eine andere Methode. Die B-Klasse sieht die ts () -Methode in A nicht, da sie statisch ist. Daher kann sie ihre eigene Methode mit dem Namen ts () deklarieren.
Wenn die Methode jedoch endgültig ist, stellt der Compiler fest, dass es in A eine ts () -Methode gibt, die in B nicht überschrieben werden sollte.
quelle
Ich denke, der Kompilierungsfehler war hier ziemlich irreführend. Es sollte nicht "Überschriebene Methode ist statisch endgültig" stehen, sondern "Überschriebene Methode ist endgültig". Der statische Modifikator spielt hier keine Rolle.
quelle
Eine statische Methode kann in Java im Gegensatz zu nicht statischen Methoden nicht überschrieben werden. Sie werden jedoch wie statische und nicht statische Datenelemente vererbt. Aus diesem Grund kann in der übergeordneten Klasse keine nicht statische Methode mit demselben Namen erstellt werden
Das
final
Schlüsselwort stellt sicher, dass der spezifische Methodenkörper bei jedem Aufruf der Methode ausgeführt wird. Wenn nun in der untergeordneten Klasse eine statische Methode mit demselben Namen erstellt und die Methode aufgerufen wird, wird die Methode in der Unterklasse ausgeführt. Dies sollte nicht der Fall sein, wenn final vor dem statischen Methodennamen in der übergeordneten Klasse steht . Daher beschränkt das letzte Schlüsselwort die Erstellung einer Methode mit demselben Namen in der untergeordneten Klasse.quelle