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:
boolean stillNeedIt = ... ;
uiControl.whenSomethingHappens( new DoSomething() {
public void resized( Rectangle r ) { ... }
public boolean canICloseNow() { return !stillNeedIt; }
public void closed() { ... }
...
} );
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:
public class BigClass implements DoSomething {
...many long methods...
protected int getDiameter() { return 5; }
}
Następnie w CleverlPanel:
uiControl.whenSomethingHappens( new BigClass() {
@Override
public int getDiameter() { return UIPanel.currentDiameter; }
} );
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.