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?

Author: aioobe, 2009-11-16

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.

Mam nadzieję, że to pomoże.
 170
Author: NawaMan,
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

Metody statyczne nie mogą być nadpisane

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.
 14
Author: Vincent Ramdhanie,
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...

 11
Author: Powerlord,
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ą.

 8
Author: Mathias Bader,
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.

 0
Author: amischiefr,
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.

 0
Author: BalusC,
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.

 0
Author: Pratik Gupta,
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