Zachowanie ostatecznej metody statycznej
Bawiłem się modyfikatorami metodą statyczną i natknąłem się na dziwne zachowanie.
Jak wiemy, metody statyczne nie mogą być nadpisywane, ponieważ są one kojarzone z klasą, A nie z instancją.
Więc jeśli mam poniższy fragment, kompiluje się dobrze
//Snippet 1 - Compiles fine
public class A {
static void ts() {
}
}
class B extends A {
static void ts() {
}
}
Ale jeśli dodam ostateczny modyfikator do statycznej metody w klasie A, kompilacja nie powiedzie się ts() w B nie może nadpisać ts () W A; metoda overridden jest statyczną ostateczną .
Dlaczego czy dzieje się tak, gdy statyczna metoda nie może być w ogóle nadpisana?
7 answers
Statyczne metody nie mogą być nadpisywane, ale mogą być ukryte. Metoda ts()
B nie nadpisuje (nie podlega polimorfizmowi) ts()
A, ale ją ukryje. Jeśli wywołujesz ts()
W B (nie A.ts()
lub B.ts()
... ponieważ nie podlega to polimorfizmowi, wywołanie ts()
W A nigdy nie zostanie przekierowane na wywołanie w B.
Słowo kluczowe final
uniemożliwi ukrycie metody. Więc nie mogą być ukryte i próba tego spowoduje błąd kompilatora.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-24 10:09:23
To nie do końca prawda. Przykładowy kod naprawdę oznacza, że metoda ts w B ukrywa metodę ts W A. więc jej nie do końca nadpisuje. Na Javaranch jest ładne Wyjaśnienie.Metody statyczne nie mogą być nadpisane
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-17 11:53:14
Statyczne metody należą do klasy, nie do instancji.
A.ts()
i B.ts()
zawsze będą osobnymi metodami.
Prawdziwy problem polega na tym, że Java pozwala wywoływać statyczne metody na obiekcie instancji. Statyczne metody z tym samym podpisem z klasy nadrzędnej są hidden , gdy są wywoływane z instancji podklasy. Nie można jednak nadpisać / ukryć ostatecznych metod .
Można by pomyśleć, że komunikat o błędzie użyje słowa Ukryty zamiast overridden...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-16 18:10:57
Możesz znaleźć się w sytuacji, aby myśleć o uczynieniu statycznej metody ostateczną, biorąc pod uwagę następujące kwestie:]}
Posiadające następujące klasy:
class A {
static void ts() {
System.out.print("A");
}
}
class B extends A {
static void ts() {
System.out.print("B");
}
}
Teraz 'poprawnym' sposobem wywoływania tych metod będzie
A.ts();
B.ts();
Co skutkowałoby AB
, ale można również wywoływać metody na instancjach:
A a = new A();
a.ts();
B b = new B();
b.ts();
Co skutkowałoby również AB
.
Rozważ teraz, co następuje:
A a = new B();
a.ts();
Które by wydrukowały A
. To może zaskoczyć. ty, ponieważ faktycznie masz obiekt klasy B
. Ale ponieważ wywołujesz go z referencji typu A
, wywoła A.ts()
. Możesz wydrukować B
z następującym kodem:
A a = new B();
((B)a).ts();
W obu przypadkach obiekt, który posiadasz, pochodzi z klasy B
. Ale w zależności od wskaźnika wskazującego na obiekt, wywołasz metodę z A
lub z B
.
Załóżmy, że jesteś twórcą klasy A
i chcesz zezwolić na podklasowanie. Ale naprawdę chcesz metoda ts()
, kiedykolwiek wywołana, nawet z podklasy, robi to, co chcesz, aby zrobiła i nie została ukryta przez wersję podklasy. Wtedy możesz zrobić to 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, przyznaję, że jest to w jakiś sposób skonstruowane, ale może to mieć sens w niektórych przypadkach.
Nie należy wywoływać metod statycznych na instancjach, lecz bezpośrednio na klasach - więc nie będziesz miał tego problemu. Na przykład IntelliJ IDEA wyświetli ostrzeżenie, jeśli wywołasz statyczną metodę na instancji, a także jeśli uczynisz statyczną metodę ostateczną.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-19 23:39:29
Metoda ts () w B nie nadpisuje metody ts () W A, jest po prostu inną metodą. Klasa B nie widzi metody ts () W A, ponieważ jest statyczna, dlatego może zadeklarować własną metodę o nazwie ts ().
Jeśli jednak metoda jest ostateczna, to kompilator wykryje, że w a znajduje się metoda ts (), która nie powinna być nadpisywana w B.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-16 17:49:20
Myślę, że błąd kompilacji był dość mylący tutaj. Nie powinno było mówić " overridden metoda jest statyczna ostateczna.", ale zamiast tego powinien był powiedzieć "overridden method is final.". Modyfikator statyczny nie ma tu znaczenia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-16 18:10:54
Statyczna metoda nie może być nadpisana w Javie, w przeciwieństwie do metod niestatycznych. Ale są one dziedziczone jak statyczne i niestatyczne elementy danych. Dlatego nie można utworzyć niestatycznej metody o tej samej nazwie w klasie nadrzędnej
class Writer {
public static void doo(){
System.out.println("sth");
}
}
class Author extends Writer{
public void doo(){
System.out.println("ok"); // error overridden method is static
}
}
Słowo kluczowe final
zapewnia, że określone ciało metody będzie uruchamiane za każdym razem, gdy wywołanie metody zostanie wywołane.
Teraz, jeśli w klasie potomnej zostanie utworzona statyczna metoda o tej samej nazwie i zostanie wykonane wywołanie tej metody, zostanie wykonana metoda w podklasie, która nie powinno być tak, jeśli final jest poprzedzone nazwą metody statycznej w klasie nadrzędnej. W związku z tym słowo kluczowe final ogranicza tworzenie metody o tej samej nazwie w klasie potomnej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-26 10:21:55