Ostatnio zacząłem patrzeć na rozwój Androida. To wróciło do świata tworzenia oprogramowania Java. Muszę przyznać, że kiedy ostatnio pracowałem z Javą, nie rozumiałem OOP tak bardzo, jak (myślę) teraz.
Korzystając głównie z C # w mojej karierze, zauważam zaskakującą różnicę w sposobie używania Java i C #.
W języku C # wydawało się, że w większości sytuacji można uniknąć dziedziczenia. Omawiane zadanie można zwykle wykonać przy użyciu konkretnych klas środowiska .NET .
W Javie, z tego, co zbieram z próbek kodu, wygląda na to, że framework Java dostarcza wiele interfejsów lub klas abstrakcyjnych, które następnie mają zostać zaimplementowane / rozszerzone przez programistę.
Wydaje się, że to zbyt duża różnica, by sprowadzić się do stylu. Jakie jest tego uzasadnienie? Czuję, że nie będę pisać czystego kodu Java, dopóki tego nie zrozumiem.
Ponadto, czy ogranicza się to tylko do zestawu SDK systemu Android, czy jest to podejście OOP obejmujące całą Javę?
Lub w inny sposób,
Co takiego jest w konstrukcji tych dwóch języków, które (jak się wydaje, zachęcają) do mniej lub bardziej dziedziczenia?
Jeśli języki traktują dziedziczenie identycznie i przy założeniu, że moja obserwacja jest prawidłowa, oznacza to, że jest to związane z projektowaniem ram / bibliotek, a nie języków. Jaka byłaby motywacja do tego rodzaju projektu?
źródło
Odpowiedzi:
Rozumiem, że w dużej mierze jest to po prostu decyzja stylistyczna. Cóż, może nie styl, ale idiomy języka / środowiska. Deweloperzy bibliotek standardowych Java stosowali się do jednego zestawu wytycznych projektowych, a programiści .NET - innego (chociaż mieli możliwość zobaczenia, jak działa podejście Javy).
W rzeczywistych językach jest bardzo mało, aby zachęcać lub zniechęcać do dziedziczenia. Tylko dwie rzeczy wydają mi się istotne:
.NET wprowadził generyczne wcześniej, zanim pojawiło się zbyt wiele kodu nieogólnego. Alternatywą jest spore dziedziczenie po wpisaniu specjalizacji.
Większą zmianą było to, że delegaci obsługiwani przez .NET. W Javie utkniesz z (anonimowym) dziedziczeniem, aby zapewnić najbardziej podstawową zmienną funkcjonalność. Prowadzi to do stosunkowo dużej różnicy w sposobie zaprojektowania kodu, aby albo wykorzystać delegatów, albo uniknąć niezręcznych struktur dziedziczenia potrzebnych do zrobienia tego w Javie.
źródło
Są to bardzo różne języki, szczególnie w tej dziedzinie. Powiedzmy, że masz klasę. W tym przypadku sprawimy, że będzie to kontrola użytkownika, coś w rodzaju pola tekstowego. Nazwij to UIControl. Teraz chcemy umieścić to w innej klasie. W tym przypadku, ponieważ w naszym przykładzie używamy interfejsu użytkownika, nazwiemy go klasą CleverPanel. Nasza instancja CleverPanel będzie chciała wiedzieć o różnych wydarzeniach związanych z instancją UIControl. Jak to zrobić?
W języku C # podstawowym podejściem jest sprawdzanie różnych zdarzeń, konfigurowanie metod, które będą wykonywane po uruchomieniu każdego interesującego zdarzenia. W Javie, w której brakuje zdarzeń, typowym rozwiązaniem jest przekazanie obiektu z różnymi metodami obsługi „zdarzeń” do metody UIControl:
Jak dotąd różnica między C # a Javą nie jest głęboka. Mamy jednak interfejs DoSomething, który nie jest potrzebny w języku C #. Ponadto ten interfejs może zawierać wiele metod, które przez większość czasu nie są potrzebne. W języku C # po prostu nie obsługujemy tego zdarzenia. W Javie tworzymy klasę, która zapewnia zerową implementację dla wszystkich metod interfejsu, DoSomethingAdapter. Teraz zamieniamy DoSomething na DoSomethingAdapter i nie musimy pisać żadnych metod dla czystego kompilacji. W rezultacie po prostu przesłoniliśmy metody, których potrzebujemy, aby program działał poprawnie. W rezultacie potrzebujemy interfejsu i używamy dziedziczenia w Javie, aby dopasować to, co zrobiliśmy ze zdarzeniami w języku C #.
To jest przykład, nie wyczerpująca dyskusja, ale daje podstawy, dlaczego w Javie jest tyle dziedziczenia w przeciwieństwie do C #.
Dlaczego Java działa w ten sposób? Elastyczność. Obiekt przekazany do whenSomethingHappens mógł zostać przekazany do CleverPanel z innego miejsca całkowicie. Może to być coś, co kilka instancji CleverPanel powinno przekazać swoim obiektom podobnym do UIControl, aby wspomóc gdzieś obiekt CleverWindow. Lub UIControl może przekazać go jednemu ze swoich komponentów.
Ponadto zamiast adaptera może istnieć gdzieś implementacja DoSomething, która ma za sobą tysiące linii kodu. Możemy stworzyć nową instancję tego i przekazać ją. Może być konieczne zastąpienie jednej metody. Częstą sztuczką w Javie jest posiadanie dużej klasy za pomocą metody takiej jak:
Następnie w CleverlPanel:
Platforma Java typu open source robi wiele z tego, co zmusza programistów do robienia więcej - zarówno dlatego, że podążają za tym przykładem, jak i po prostu, aby go użyć. Wydaje mi się, że podstawową konstrukcją tego języka jest projektowanie frameworka firmy Sun, a programista Java korzysta z technik, gdy nie używa frameworka.
Łatwo jest stworzyć klasę w locie w Javie. Do klasy, anonimowej lub nazwanej, należy odwoływać się tylko w jednym małym bloku kodu ukrytym głęboko w jednej metodzie. Można go stworzyć całkowicie nowy lub przez niewielkie modyfikacje bardzo dużej, istniejącej klasy. (A istniejąca klasa może znajdować się na najwyższym poziomie we własnym pliku lub zagnieżdżona w klasie najwyższego poziomu lub zdefiniowana tylko w jednym bloku kodu). Nowa instancja klasy może mieć pełny dostęp do wszystkich danych obiektu tworzącego. Nowe wystąpienie można przekazać i wykorzystać w całym programie, reprezentując obiekt, który go utworzył.
(Nawiasem mówiąc, zauważ, że duże zastosowanie dziedziczenia tutaj - podobnie jak w innych miejscach w Javie - jest po prostu do OSUSZANIA. Pozwala innym klasom na ponowne użycie tego samego kodu. Zwróć także uwagę na łatwość dziedziczenia w Javie, która zachęca do tego. )
Ponownie, nie jest to wyczerpująca dyskusja; Właśnie drapię tutaj powierzchnię. Ale tak, istnieje zaskakująca różnica w sposobie używania dziedziczenia między Javą a C #. Są to pod tym względem bardzo różne języki. To nie twoja wyobraźnia.
źródło
Nie ma absolutnie żadnej różnicy w sposobie obsługi dziedziczenia między Javą a C #. Kiedy faktycznie użyjesz dziedziczenia lub kompozycji, jest to zdecydowanie decyzja projektowa i w żadnym wypadku nie jest to coś, co zachęca lub zniechęca Java lub C #. Proponuję przeczytać ten artykuł .
Mam nadzieję, że pomogłem!
źródło