Pytanie w Javie, dlaczego nie mogę zdefiniować abstrakcyjnej metody statycznej? na przykład
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
java
abstract-class
static-methods
hhafez
źródło
źródło
Odpowiedzi:
Ponieważ „streszczenie” oznacza: „Nie implementuje żadnej funkcji”, a „statyczny” oznacza: „Istnieje funkcjonalność, nawet jeśli nie masz instancji obiektu”. I to jest logiczna sprzeczność.
źródło
abstract static
miałaby doskonały sens. Byłaby to metoda samego obiektu klasy, którą obiekty podklasy muszą zaimplementować. Oczywiście sposób, w jaki stoją twoje odpowiedzi, jest prawidłowy, mimo że mam obsesję na punkcie języka.abstract static
: Funkcja X, która jest „zaimplementowana w podklasie”, nie może być jednocześnie „wykonana na klasie” - tylko na podklasie . Gdzie to nie jest już abstrakcyjne.static
nie oznacza „niepusty” - to tylko konsekwencja tego, że Java nie pozwala abstrakcyjnym metodom statycznym. Oznacza to „możliwe do wywołania w klasie”. (Powinno to oznaczać „wywołanie tylko w klasie”, ale to już inna kwestia.) Jeśliabstract static
metody obsługiwane przez Javę oczekiwałbym, że będzie to oznaczać, że metoda 1) musi być zaimplementowana przez podklasy, a 2) jest metodą klasy podklasy. Niektóre metody po prostu nie mają sensu jako metody instancji. Niestety Java nie pozwala na określenie tego podczas tworzenia abstrakcyjnej klasy bazowej (lub interfejsu).Słaby wygląd języka. O wiele bardziej efektywne byłoby bezpośrednie wywoływanie statycznej metody abstrakcyjnej niż tworzenie instancji wyłącznie w celu użycia tej metody abstrakcyjnej. Jest to szczególnie prawdziwe, gdy używa się klasy abstrakcyjnej jako obejścia niemożności rozszerzenia enum, co jest kolejnym złym przykładem projektu. Mam nadzieję, że rozwiążą te ograniczenia w następnym wydaniu.
źródło
static
samego siebie jest już naruszeniem ....Nie można zastąpić metody statycznej, więc uczynienie jej abstrakcyjną byłoby bez znaczenia. Co więcej, metoda statyczna w klasie abstrakcyjnej należałaby do tej klasy, a nie do klasy nadrzędnej, więc i tak nie można jej użyć.
źródło
abstract
Adnotacji do metody wskazuje, że metoda musi być nadpisane w podklasie.W Javie
static
elementu (metody lub pola) nie można zastąpić podklasami (niekoniecznie jest to prawda w innych językach obiektowych, patrz SmallTalk.) Elementstatic
członkowski może być ukryty , ale zasadniczo różni się od przesłaniania .Ponieważ elementów statycznych nie można zastąpić w podklasie,
abstract
adnotacja nie może zostać do nich zastosowana.Nawiasem mówiąc - inne języki obsługują dziedziczenie statyczne, podobnie jak dziedziczenie instancji. Z perspektywy składni te języki zwykle wymagają włączenia nazwy klasy do instrukcji. Na przykład w Javie, przy założeniu, że piszesz kod w klasie A, są to równoważne instrukcje (jeśli metoda A () jest metodą statyczną i nie ma metody instancji o tej samej sygnaturze):
i
W SmallTalk nazwa klasy nie jest opcjonalna, więc składnia jest następująca (zwróć uwagę, że SmallTalk nie używa. Do oddzielenia „podmiotu” i „czasownika”, ale zamiast tego używa go jako terminatora statemend):
Ponieważ nazwa klasy jest zawsze wymagana, poprawną „wersję” metody można zawsze ustalić, przechodząc przez hierarchię klas. Za to, co warto, czasami tęsknię
static
dziedziczenia i ugryziony przez brak statycznego dziedziczenia w Javie, kiedy zaczynałem od niego. Dodatkowo SmallTalk jest typu kaczego (i dlatego nie obsługuje programu według umowy). Zatem nie maabstract
modyfikatora dla członków klasy.źródło
Zadałem również to samo pytanie, oto dlaczego
Ponieważ klasa Abstract mówi, nie da implementacji i nie pozwoli na jej podklasę
więc podklasa musi zastąpić metody nadklasy,
ZASADA 1 - Nie można zastąpić metody statycznej
Ponieważ elementy i metody statyczne są elementami czasu kompilacji, dlatego przeciążanie (polimorfizm czasu kompilacji) metod statycznych jest dozwolone zamiast zastępowania (polimorfizm środowiska uruchomieniowego)
Więc nie mogą być abstrakcyjni.
Nie ma czegoś takiego jak abstrakcyjny statyczny <--- Niedozwolone w Java Universe
źródło
abstract static
zobaczyć stackoverflow.com/questions/370962/... . Prawdziwy powód dlaczego Java nie pozwala metody statyczne być zastąpiona jest ponieważ Java nie pozwala metody statyczne być nadpisane.foo(String)
to nie to samo, cofoo(Integer)
- to wszystko.To okropny projekt językowy i naprawdę nie ma powodu, dla którego to niemożliwe.
W rzeczywistości oto implementacja tego, jak MOŻNA to zrobić w JAVA :
================= Stary przykład poniżej =================
Poszukaj getRequest i getRequestImpl ... setInstance można wywołać w celu zmiany implementacji przed wykonaniem wywołania.
Używane w następujący sposób:
źródło
abstract static
metody zadanej w pytaniu i napisałeś pogrubioną czcionką MOŻNA ZROBIĆ W JAVA . To całkowicie mylące.Metodę abstrakcyjną definiuje się tylko po to, aby można ją było zastąpić w podklasie. Jednak metod statycznych nie można zastąpić. Dlatego posiadanie abstrakcyjnej, statycznej metody jest błędem podczas kompilacji.
Teraz następne pytanie brzmi: dlaczego nie można zastąpić metod statycznych?
Jest tak, ponieważ metody statyczne należą do konkretnej klasy, a nie do jej instancji. Jeśli spróbujesz zastąpić metodę statyczną, nie pojawi się żaden błąd kompilacji ani środowiska wykonawczego, ale kompilator po prostu ukryje metodę statyczną nadklasy.
źródło
Metoda statyczna z definicji nie musi wiedzieć
this
. Zatem nie może to być metoda wirtualna (która jest przeciążona zgodnie z informacjami dynamicznej podklasy dostępnymi za pośrednictwemthis
); zamiast tego przeciążenie metody statycznej opiera się wyłącznie na informacjach dostępnych w czasie kompilacji (oznacza to: po odwołaniu się do statycznej metody nadklasy wywołuje się metodę nadklasy, ale nigdy metodę podklasy).Zgodnie z tym abstrakcyjne metody statyczne byłyby zupełnie bezużyteczne, ponieważ nigdy nie zastąpi się odniesienia przez jakieś określone ciało.
źródło
Widzę, że istnieją już bogie odpowiedzi, ale nie widzę żadnych praktycznych rozwiązań. Oczywiście jest to prawdziwy problem i nie ma dobrego powodu, aby wykluczyć tę składnię w Javie. Ponieważ w pierwotnym pytaniu brakuje kontekstu, w którym może to być potrzebne, przedstawiam zarówno kontekst, jak i rozwiązanie:
Załóżmy, że masz metodę statyczną w grupie identycznych klas. Te metody nazywają metodę statyczną specyficzną dla klasy:
doWork()
metodyC1
iC2
są identyczne. Może istnieć wiele takich przypadków:C3
C4
itd. Gdybystatic abstract
było to dozwolone, wyeliminowałbyś duplikat kodu, wykonując coś takiego:ale nie skompiluje się, ponieważ
static abstract
kombinacja nie jest dozwolona. Można to jednak obejść za pomocąstatic class
konstrukcji, która jest dozwolona:Dzięki temu rozwiązaniu jedynym zduplikowanym kodem jest
źródło
C1.doWork()
lubC2.doWork()
Ale nie możesz zadzwonićC.doWork()
. Również w podanym przez ciebie przykładzie, który nie będzie działał, załóżmy, że gdyby było dozwolone, to w jaki sposób klasaC
znajdzie implementacjędoMoreWork()
? Na koniec nazwałbym twój kod kontekstowy złym projektem. Dlaczego? po prostu dlatego, że utworzono osobną funkcję dla kodu, która jest unikalna, zamiast tworzyć funkcję dla kodu, który jest wspólny, a następnie implementować funkcję statyczną w klasieC
. To jest łatwiejsze !!!Załóżmy, że istnieją dwie klasy
Parent
iChild
.Parent
jestabstract
. Deklaracje są następujące:Oznacza to, że każde wystąpienie
Parent
musi określać sposóbrun()
wykonania.Załóżmy jednak, że
Parent
tak nie jestabstract
.Oznacza to, że
Parent.run()
wykona metodę statyczną.Definicja
abstract
metody to „Metoda zadeklarowana, ale nie zaimplementowana”, co oznacza, że sama niczego nie zwraca.Definicja
static
metody to „Metoda, która zwraca tę samą wartość dla tych samych parametrów bez względu na instancję, w której jest wywoływana”.An
abstract
wartość zwracana METHOD może ulec zmianie wraz ze zmianami instancji.static
Metoda nie będzie.static abstract
Metoda jest dość dużo metoda, w której wartość zwracana jest stała, ale niczego nie powrócić. To logiczna sprzeczność.Poza tym
static abstract
metoda nie ma zbyt wiele powodów .źródło
Klasa abstrakcyjna nie może mieć metody statycznej, ponieważ abstrakcja jest wykonywana w celu osiągnięcia WIĄZANIA DYNAMICZNEGO, podczas gdy metody statyczne są statycznie powiązane z ich funkcjonalnością. Metoda statyczna oznacza zachowanie niezależne od zmiennej instancji, więc nie jest wymagana żadna instancja / obiekt. Tylko klasa. Metody statyczne należą do klasy, a nie do obiektu. Są one przechowywane w obszarze pamięci znanym jako PERMGEN, skąd jest współdzielony z każdym obiektem. Metody w klasie abstrakcyjnej są dynamicznie powiązane z ich funkcjonalnością.
źródło
Deklaracja metody jako
static
oznacza, że możemy wywołać tę metodę po nazwie klasy, a jeśli ta klasaabstract
również jest, nie ma sensu nazywać go, ponieważ nie zawiera on żadnego ciała, a zatem nie możemy zadeklarować metody zarówno jako, jakstatic
iabstract
.źródło
Ponieważ metody abstrakcyjne należą do klasy i nie mogą zostać zastąpione przez klasę implementującą, nawet jeśli istnieje metoda statyczna z tym samym podpisem, ukrywa metodę, nie zastępując jej. Nie ma zatem znaczenia, aby deklarować metodę abstrakcyjną jako statyczną, ponieważ nigdy nie otrzyma ona ciała, dlatego też błąd czasu kompilacji.
źródło
Metodę statyczną można wywołać bez wystąpienia klasy. W twoim przykładzie możesz wywołać foo.bar2 (), ale nie foo.bar (), ponieważ dla bar potrzebujesz instancji. Działa następujący kod:
Wywołanie metody statycznej spowoduje wykonanie zawsze tego samego kodu. W powyższym przykładzie, nawet jeśli przedefiniujesz bar2 w ImplementsFoo, wywołanie var.bar2 () wykona foo.bar2 ().
Jeśli bar2 nie ma teraz implementacji (to znaczy streszczenie), możesz wywołać metodę bez implementacji. To bardzo szkodliwe.
źródło
Wydaje mi się, że znalazłem odpowiedź na to pytanie w postaci tego, dlaczego metody interfejsu (które działają jak metody abstrakcyjne w klasie nadrzędnej) nie mogą być statyczne. Oto pełna odpowiedź (nie moja)
Zasadniczo metody statyczne można wiązać w czasie kompilacji, ponieważ aby je wywołać, należy określić klasę. Różni się to od metod instancji, dla których klasa odwołania, z którego wywołujesz metodę, może być nieznana w czasie kompilacji (dlatego który blok kodu jest wywoływany, można określić tylko w czasie wykonywania).
Jeśli wywołujesz metodę statyczną, znasz już klasę, w której jest ona zaimplementowana, lub wszelkie jej bezpośrednie podklasy. Jeśli zdefiniujesz
Wtedy każde
Foo.bar();
połączenie jest oczywiście nielegalne i zawsze będziesz używaćFoo2.bar();
.Mając to na uwadze, jedynym celem statycznej abstrakcyjnej metody byłoby wymuszenie podklas w celu wdrożenia takiej metody. Na początku możesz pomyśleć, że jest to BARDZO złe, ale jeśli masz parametr typu ogólnego,
<E extends MySuperClass>
dobrze byłoby zagwarantować za pośrednictwem interfejsu, któryE
może.doSomething()
. Należy pamiętać, że ze względu na wymazywanie typów, generycy istnieją tylko w czasie kompilacji.Czy byłoby to przydatne? Tak, a może dlatego Java 8 zezwala na metody statyczne w interfejsach (choć tylko z domyślną implementacją). Dlaczego nie abstrakcyjne metody statyczne z domyślną implementacją w klasach? Po prostu dlatego, że abstrakcyjna metoda z domyślną implementacją jest w rzeczywistości konkretną metodą.
Dlaczego nie abstrakcyjne / statyczne metody interfejsu bez domyślnej implementacji? Najwyraźniej tylko z powodu sposobu, w jaki Java identyfikuje blok kodu, który musi wykonać (pierwsza część mojej odpowiedzi).
źródło
Ponieważ klasa abstrakcyjna jest koncepcją OOPS, a elementy statyczne nie są częścią OOPS ...
Teraz chodzi o to, że możemy zadeklarować statyczne pełne metody w interfejsie i możemy wykonać interfejs, deklarując główną metodę wewnątrz interfejsu
źródło
Idea posiadania abstrakcyjnej metody statycznej polegałaby na tym, że nie można użyć tej konkretnej klasy abstrakcyjnej bezpośrednio dla tej metody, ale tylko pierwsza pochodna może zaimplementować tę metodę statyczną (lub dla ogólnych: rzeczywistej klasy ogólnej posługiwać się).
W ten sposób można na przykład utworzyć klasę abstrakcyjną sortableObject lub nawet interfejs z (automatycznymi) abstrakcyjnymi metodami statycznymi, która określa parametry opcji sortowania:
Teraz możesz zdefiniować sortowalny obiekt, który można sortować według głównych typów, które są takie same dla wszystkich tych obiektów:
Teraz możesz utworzyć
który może pobierać typy, zbudować menu podręczne, aby wybrać typ do sortowania i posortować listę, pobierając dane z tego typu, a także uzyskać funkcję dodawania, która po wybraniu typu sortowania może automatycznie -sortuj nowe elementy w. Zauważ, że instancja SortableList może bezpośrednio uzyskać dostęp do metody statycznej „T”:
Problem z koniecznością użycia instancji polega na tym, że SortableList może jeszcze nie zawierać elementów, ale już musi zapewnić preferowane sortowanie.
Cheerio, Olaf.
źródło
Po pierwsze, kluczowy punkt dotyczący klas abstrakcyjnych - nie można utworzyć instancji klasy abstrakcyjnej (patrz wiki ). Dlatego nie można utworzyć żadnego wystąpienia klasy abstrakcyjnej.
Teraz sposób, w jaki Java radzi sobie z metodami statycznymi, polega na udostępnianiu metody wszystkim instancjom tej klasy.
Jeśli więc nie można utworzyć instancji klasy, klasa ta nie może mieć abstrakcyjnych metod statycznych, ponieważ metoda abstrakcyjna zaczyna być rozszerzana.
Bum.
źródło
Zgodnie z dokumentacją Java :
W Javie 8 wraz z domyślnymi metodami dozwolone są również metody statyczne w interfejsie. Ułatwia nam to organizowanie metod pomocniczych w naszych bibliotekach. Możemy zachować metody statyczne specyficzne dla interfejsu w tym samym interfejsie, a nie w osobnej klasie.
Dobrym przykładem tego jest:
zamiast
Inny przykład użycia metod statycznych podano również w samym dokumencie :
źródło
Ponieważ „streszczenie” oznacza, że metoda ma być nadpisana i nie można zastąpić metod „statycznych”.
źródło
Zwykłe metody mogą być abstrakcyjne, gdy mają być zastąpione przez podklasy i wyposażone w funkcje. Wyobraź sobie, że klasa
Foo
jest przedłużonaBar1, Bar2, Bar3
itd. Tak więc każda z nich będzie miała własną wersję klasy abstrakcyjnej zgodnie z własnymi potrzebami.Otóż metody statyczne z definicji należą do klasy, nie mają one nic wspólnego z obiektami klasy ani obiektami jej podklas. Nie potrzebują nawet ich istnienia, można z nich korzystać bez tworzenia instancji klas. Dlatego muszą być gotowe do pracy i nie mogą zależeć od podklas, aby dodać im funkcjonalność.
źródło
Ponieważ streszczenie jest słowem kluczowym stosowanym nad metodami abstrakcyjnymi, nie określają treści. A jeśli mówimy o statycznym słowie kluczowym, należy ono do obszaru klasy.
źródło
ponieważ jeśli używasz w klasie dowolnego elementu statycznego lub zmiennej statycznej, ładuje się on podczas ładowania klasy.
źródło
Możesz to zrobić za pomocą interfejsów w Javie 8.
Oto oficjalna dokumentacja na ten temat:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
źródło
Ponieważ jeśli klasa rozszerza klasę abstrakcyjną, musi zastąpić metody abstrakcyjne, co jest obowiązkowe. A ponieważ metody statyczne są metodami klasy rozstrzyganymi w czasie kompilacji, podczas gdy metody zastępowane są metodami instancji rozwiązywanymi w czasie wykonywania i po dynamicznym polimorfizmie.
źródło