Być może będziesz w stanie pomyśleć o ostatecznym zakończeniu metody statycznej, biorąc pod uwagę następujące kwestie:
Posiadanie następujących klas:
class A {
static void ts() {
System.out.print("A");
}
}
class B extends A {
static void ts() {
System.out.print("B");
}
}
Teraz „poprawnym” sposobem na wywołanie tych metod byłoby
A.ts();
B.ts();
co spowoduje, AB
ale możesz również wywołać metody w instancjach:
A a = new A();
a.ts();
B b = new B();
b.ts();
co by też skutkowało AB
.
Rozważmy teraz następujące kwestie:
A a = new B();
a.ts();
to by się wydrukowało A
. To może cię zaskoczyć, ponieważ tak naprawdę masz przedmiot klasy B
. Ale ponieważ wywołujesz go z referencji typu A
, zadzwoni A.ts()
. Możesz wydrukować B
za pomocą następującego kodu:
A a = new B();
((B)a).ts();
W obu przypadkach posiadany obiekt pochodzi z klasy B
. Ale w zależności od wskaźnika, który wskazuje na obiekt, wywołasz metodę from A
lub from B
.
Teraz powiedzmy, że jesteś twórcą klasy A
i chcesz zezwolić na tworzenie podklas. Ale naprawdę chcesz ts()
, aby metoda , kiedykolwiek wywołana, nawet z podklasy, robiła to, co chcesz, a nie była ukryta przez wersję podklasy. Wtedy możesz to zrobić final
i zapobiec ukryciu go w podklasie. I możesz być pewien, że poniższy kod wywoła metodę z Twojej klasy A
:
B b = new B();
b.ts();
Ok, wprawdzie jest to w jakiś sposób skonstruowane, ale w niektórych przypadkach może to mieć sens.
Nie powinieneś wywoływać metod statycznych na instancjach, ale bezpośrednio na klasach - wtedy nie będziesz miał tego problemu. Na przykład IntelliJ IDEA wyświetli ostrzeżenie, jeśli wywołasz metodę statyczną na instancji, a także, jeśli sprawisz, że metoda statyczna zostanie ostateczna.