pasażer OT pasażer OT
513
BLOG

Uczę się Javy (1)

pasażer OT pasażer OT Nauka Obserwuj temat Obserwuj notkę 10

 


W dzisiejszych czasach znajomość języków to podstawa. Dobrze znać zwłaszcza te popularne, zatem pora na naukę Javy, bodaj najpowszechniej dziś używanego języka programowania.

 
Do Javy przymierzałem się kilka razy. Za każdym razem porzucałem naukę, głównie z powodu lenistwa oczywiście, częściowo jednak także dlatego, bo język wydawał mi się mało ciekawy, bez charakteru. Tożsamość Javy, jak mi się wydawało, budowana jest na tym, czym ma się różnić się od C++ i co robić od niego lepiej. Jako rzeczywiście nowy język, bardziej podobał mi się C#.

 
Tamto wrażenie nie minęło, ale nie ma co wybrzydzać. Skoro wszyscy mówią "Java", trzeba się z Javą zapoznać. Blog ten ma być, z założenia, luźnym zapisem wrażeń z nauki. Dla mnie, ma stanowić czynnik mobilizujący i porządkujący wiedzę. Nie tylko nt. Javy zresztą - będzie zapewne także o innych językach oraz konceptach w programowaniu w ogóle. Być może ktoś znajdzie tu coś ciekawego dla siebie, mam taką nadzieję. Nie ma co ukrywać, liczę też na to, że znający Javę, i nie tylko, zechcą podzielić się swoimi uwagami w komentarzach, w szczególności, że wytkną mi wszystkie głupoty, jakie napiszę.
 

* * *

 
Jedną z pierwszych informacji, jakie napotyka osoba poznająca Javę, jest komunikat: "w Javie wszystko jest klasą". (Czasem można też przeczytać "w Javie wszystko jest obiektem", ale ta wersja, jak sądzę, jest dalsza od prawdy). Brzmi nieźle, efektownie, ale co konkretnie oznacza?

 
Okazuje się, że w Javie wszystkie dane i procedury muszą być związane z jakąś klasą, tzn. nie mogą być zadeklarowane i użyte inaczej, niż tylko w kontekście klasy. Ów związek z klasą może być bezpośredni – np. procedury (funkcje, jeśli ktoś woli) są w Javie zawsze składowymi klasy, czyli metodami, lub pośredni – zmienne lokalne procedury są pośrednio związane z klasą, właśnie poprzez swoją procedurę. Dostępne są, przy tym, inne typy niż klasy - np. zwykłe, dobrze znane z wielu języków "typy proste".

 
Widać z powyższego, że w Javie nie tyle "wszystko jest klasą", co "wszystko jest wewnątrz jakiejś klasy". (W rzeczywistości - prawie wszystko, o wyjątkach nieco dalej). To drugie sformułowanie należy uznać za wyjątkowo trafne, bowiem w Javie nie tylko wszystko musi być związane z klasą logicznie, ale także musi być "napisane wewnątrz klasy", czyli znajdować się w ciele klasy (w szczególności, inaczej niż w C++, nie można definiować metod poza ciałem klasy).

 
Nasuwa się pytanie, dlaczego przyjęto takie założenie, czy tylko dla porządku i spójności kodu, czy może ze snobizmu - żeby było "w pełni obiektowo", czy też kryje się za tym coś więcej, co być może daje programiście jeszcze jakieś profity? To się pewnie okaże. Już jednak napisanie i skompilowanie prostego programu pozwala stwierdzić, że w Javie "paczkowanie" w klasy odbywa się nie tylko na poziomie kodu źródłowego, ale również na poziomie "kodu pośredniego" - każda klasa jest kompilowana do osobnego pliku. Interesujące.

 
Interesujący jest również fakt, że konieczność podziału całego kodu pomiędzy klasy sprzyja dość niestandardowemu, czy może - nieideologicznemu, podejściu do prezentacji samego pojęcia klasy przez nauczających o Javie. W niektórych podręcznikach, internetowych kursach Javy, przedstawia się wstępnie klasę jako "jednostkę programu", coś, co służy do organizacji, podziału kodu (coś, co można by porównać do namespace z C++ lub modułu z Pascala). Osoba zapoznająca się dopiero z klasami ma w ten sposób szansę zobaczyć program napisany w Javie przede wszystkim jako zbiór zmiennych i procedur, tyle że pogrupowanych - co daje paradoksalną sprzeczność z założeniem o "obiektowości" języka, z "wysoką" ideologią programowania obiektowego w ogóle.

 
Zasada "wszystko w Javie jest wewnątrz klasy" ma wyjątki. Można by ją uogólnić, tak aby ich nie miała. Brzmiałaby wtedy - "wszystko w Javie znajduje się wewnątrz zdefiniowanego i nazwanego przez programistę typu". W Javie, oprócz klas, takimi typami są interfejsy i typy wyliczeniowe. Bardzo ograniczony zbiór - mniejszy niż w innych językach, a ponadto interfejsy i typy wyliczeniowe są to byty, powiedzmy, znacznie mniej "nośne programistycznie", niż klasy - zatem, rzeczywiście, "prawie wszystko jest wewnątrz klasy". Warto jednak zwrócić uwagę na to, że typy wyliczeniowe wprowadzono, jak czytam, dopiero w wersji SE 5.0, co mogłoby wskazywać na pewne kruszenie, z biegiem czasu, początkowych żelaznych zasad.
Z ostatniej chwili: jak się jednak właśnie dowiaduję, typ wyliczeniowy to w Javie jest też klasa, tyle że fakt ten pozostaje w niejakim ukryciu. Cóż, widzę, że lekko nie będzie...

 
Jak każda restrykcja, "obowiązek klasowy" musi powodować odreagowanie w postaci uaktywnienia sposobów obejścia nakazu. Nie zawsze przecież wszystkie elementy programu pasują do modelu obiektowego, niektóre elementy z natury obiektowe nie są. W Javie takie odreagowanie objawia się, prawdopodobnie, popularnością składowych statycznych. Składowe te, jak wiadomo, są przeznaczone do pracy na rzecz samej klasy, a nie jej instancji (obiektów), istnieją więc i są gotowe do użycia przez cały czas trwania programu. Nadają się zatem świetnie do imitacji zmiennych globalnych oraz procedur ogólnodostępnych (nie metod). Pisząc program w Javie, korzystamy zawsze ze składowej statycznej co najmniej raz - taką bowiem musi być obowiązkowa metoda main, od której zaczyna się wykonywanie programu:

 
public class ShowSomething
{
   public static void main( String[] args)
   {
      System.out.println( "Witaj, rybo");
   }
}

 
Szczególnie popularne powinny być klasy, których wszystkie składowe są statyczne, a zatem klasy, których instancji nikt nie zamierza tworzyć, a których przeznaczeniem jest dostarczenie zmiennych i procedur imitujących zmienne globalne i procedury ogólnego przeznaczenia. Nie znaczy to zresztą, że takie klasy muszą być tworem sztucznym, a ich definiowanie niewygodną koniecznością. Przeciwnie, klasy te, jak wszystkie inne, mogą odgrywać pozytywną rolę porządkującą. Na przykład, wywołania metod statycznych z bibliotecznej w Javie klasy Math:

 
x = Math.cos( arg1);
y = Math.sqrt( arg2);

 
są chyba bardziej przejrzyste i czytelne, niż gdyby były wykonywane bez kwalifikatora "Math.".

 
Na koniec quiz dla Czytelnika: czy można utworzyć obiekt klasy, której wszystkie składowe są statyczne? (W Javie, C++ lub innym języku).

 
pasażer OT
O mnie pasażer OT

Nowości od blogera

Komentarze

Pokaż komentarze (10)

Inne tematy w dziale Technologie