Dlaczego klasy Java nie mogą mieć pól abstrakcyjnych, tak jak mogą mieć metody abstrakcyjne?
Na przykład: Mam dwie klasy, które rozszerzają tę samą abstrakcyjną klasę bazową. Każda z tych dwóch klas ma metodę, która jest identyczna, z wyjątkiem stałej String, która jest komunikatem o błędzie. Gdyby pola mogły być abstrakcyjne, mógłbym uczynić tę stałą abstrakcją i przeciągnąć metodę do klasy bazowej. Zamiast tego muszę utworzyć metodę abstrakcyjną, wywoływaną getErrMsg()
w tym przypadku, która zwraca String, przesłania tę metodę w dwóch klasach pochodnych, a następnie mogę wywołać metodę (która teraz wywołuje metodę abstrakcyjną).
Dlaczego nie mogłem po prostu zrobić abstrakcji na początku? Czy Java mogła na to pozwolić?
Odpowiedzi:
Możesz zrobić to, co opisałeś, mając końcowe pole w swojej klasie abstrakcyjnej, które jest inicjowane w jego konstruktorze (nieprzetestowany kod):
Jeśli twoja klasa potomna „zapomni” o zainicjowaniu finału przez superkonstruktor, kompilator wyświetli
ostrzeżenieo błędzie, tak jak wtedy, gdy metoda abstrakcyjna nie jest zaimplementowana.źródło
Base
należy to zgłosićabstract
.Nie widzę w tym sensu. Możesz przenieść funkcję do klasy abstrakcyjnej i po prostu przesłonić niektóre chronione pola. Nie wiem, czy to działa ze stałymi, ale efekt jest taki sam:
Chodzi ci więc o to, że chcesz wymusić implementację / nadpisanie / cokolwiek
errorMsg
w podklasach? Myślałem, że chciałeś mieć metodę w klasie bazowej i nie wiedziałeś wtedy, jak sobie radzić z polem.źródło
protected String errorMsg;
co w jakiś sposób wymusza ustawienie wartości w podklasach. Jest podobny do tych klas abstrakcyjnych, które w rzeczywistości implementują wszystkie metody jako symbole zastępcze, dzięki czemu programiści nie muszą implementować każdej metody, chociaż jej nie potrzebują.protected String errorMsg;
ma nie dochodzić, że można ustawić wartość w podklasach.Oczywiście można było to zaprojektować, aby na to pozwolić, ale pod osłonami nadal musiałby wykonywać dynamiczne wysyłanie, a zatem wywołanie metody. Projekt Javy (przynajmniej na początku) był do pewnego stopnia próbą bycia minimalistą. Oznacza to, że projektanci starali się unikać dodawania nowych funkcji, jeśli można je łatwo symulować za pomocą innych funkcji już w języku.
źródło
Czytając swój tytuł, pomyślałem, że odnosisz się do abstrakcyjnych członków instancji; i nie widziałem dla nich pożytku. Ale abstrakcyjne statyczne elementy to zupełnie inna sprawa.
Często marzyłem, żebym mógł zadeklarować metodę podobną do poniższej w Javie:
Zasadniczo chciałbym nalegać, aby konkretne implementacje mojej klasy nadrzędnej zapewniały statyczną metodę fabryki z określonym podpisem. Pozwoliłoby mi to uzyskać odniesienie do konkretnej klasy
Class.forName()
i mieć pewność, że mogę ją skonstruować w wybranej przeze mnie konwencji.źródło
@autowired T fieldName
. JeśliT
jest zdefiniowane jako coś podobnegoT extends AbstractController
, typ erasure powoduje, że pole jest generowane jako typAbstractController
i nie może być automatycznie przypisane, ponieważ nie jest konkretne i nie jest unikalne. Generalnie zgadzam się, że nie mają dla nich większego pożytku, a zatem nie pasują do tego języka. Nie zgodziłbym się z tym, że NIE ma dla nich pożytku.Inną opcją jest zdefiniowanie pola jako publicznego (jeśli chcesz, jeśli wolisz) w klasie bazowej, a następnie zainicjowanie tego pola w konstruktorze klasy bazowej, w zależności od aktualnie używanej podklasy. Jest to trochę podejrzane, ponieważ wprowadza zależność cykliczną. Ale przynajmniej nie jest to zależność, która może się zmienić - tj. Podklasa będzie istnieć lub nie będzie istnieć, ale metody lub pola podklasy nie mogą wpływać na wartość
field
.źródło