Paradygmaty programowania obiektowego w Javie

Poprzedni wpis dotyczył pętli oraz przepływów sterowania. Do tej pory poznaliśmy podstawy tego języka nie zagłębiając się w bardziej zaawansowane funkcje. Czas to zmienić, aby w pełni zacząć korzystać z dobrodziejstw, które dostarcza nam Java.

W tej części szkolenia Javy poznamy pojęcie programowania obiektowego – kluczowego, gdyż ona w pełni go implementuje. Jak się przekonaliśmy we wpisie o uruchomieniu IDE Eclipse, aby wywołać metodę main() należy utworzyć klasę. Programiści, którzy do tej pory mieli styczność z programowaniem proceduralnym powinni zwrócić uwagę na inne podejście do procedur i danych.

Klasa – w programowaniu obiektowym

Klasa jest własnym, definiowanym typem danych, z którego tworzy się obiekty (egzemplarze klasy). Składa się z pól (które możemy traktować jako dane) oraz metod (algorytmów, które operują na polach). Ich obecność nie jest obowiązkowa – można napisać klasę, która zawiera jedynie pola lub nawet zostawić ją pustą.

Klasy posiadają różne przeznaczenie – w zależności od potrzeb programisty. W bibliotece standardowej dostarczonej wraz z pakietem mamy do dyspozycji kilka tysięcy klas, które służą do prostszych rzeczy jak obsługa łańcuchów znakowych lub dat, przez bardziej zaawansowane reprezentacje danych jak listy (ang. Linked List), drzewa binarnych poszukiwań (ang. BST), tablice o zmiennych rozmiarach (ang. Array List) do zaawansowanego programowania sieciowego, obsługę protokołów sieciowych oraz obsługę aplikacji w architekturze klient serwer.

Paradygmaty programowania obiektowego

Programowanie obiektowe (ang. object oriented programming) różni się tym od proceduralnego, że łączy w sobie dane z algorytmami, które je przetwarzają. Jak sama nazwa wskazuje główne operacje będą wykonywane na obiektach, zmieniając ich stan.

Dziedziczenie

Pomimo ogromnej biblioteki standardowej niezbędne jest tworzenie własnych klas na potrzeby programu. Zawsze w fazie projektowania warto dokładnie zastanowić się jakie relacje występują między klasami, aby wykorzystać mechanizm dziedziczenia i zmniejszyć ilość kodu. Każdy pracownik firmy jest osobą, w związku z tym informacje ogólne można zawrzeć w klasie Osoba, natomiast pole sala, które reprezentuje salę, za którą odpowiada dany kelner w klasie Kelner. Ta ostatnia posiada wszystkie pola i metody z klasy Osoba.

Hermetyzacja

Jedną z najważniejszych cech programowania obiektowego jest hermetyzacja danych, czyli ukrywanie szczegółów implementacyjnych przed programistą i dostępie do nich poprzez metody. Dzięki tej cesze obiekty nie mogę zmieniać stanu innych obiektów – tylko metody wywołane na rzecz danego obiektu mogą wpłynąć na jego stan.

Abstrakcja

Dzięki abstrakcji wiemy jakie metody jakie metody mogą być wywołane (ale nie znając szczegółów). Przykładem może być metoda, którą można zapewne zaimplementować u większości ludzi – zaparz herbatę. Interesuje nas jej efekt czyli czy herbata jest dobra, natomiast na tym poziomie abstrakcji nie interesuje nas czy ktoś użyje czajnika elektrycznego do podgrzania wody czy rozpali ognisko.

Polimorfizm

Polimorfizm to wykorzystanie jednego schematu do obiektów różnego typu np. kolekcja może dotyczyć znaczków pocztowych jak i samochodów.
Klasa Object – klasa po której dziedziczą wszystkie klasy w Javie.

Obiekt

Jest to konkretny egzemplarz utworzony z klasy (czasem nazywany konkretem). Każdy obiekt posiada trzy cechy.

  • Zachowanie – metody, które można wywołać na jego rzecz. Każdy obiekt danej klasy posiada dokładnie te same metody jednak w zależności od stanu zachowanie może być inne.
  • Stan – wartości poszczególnych pól obiektu. Zgodnie z zasadą hermetyzacji danych możliwa jest tylko po wywołaniu metody na obiekcie.
  • Tożsamość – każdy obiekt można rozróżnić mimo identycznych wartości pól. Obiekty tej samej klasy zawsze mają inną tożsamość – nawet kopie.

Tworzenie własnej klasy – pierwsze kroki

Przypuśćmy, że w naszym programie chcemy odwzorować w przystępny sposób informacje o samochodzie tak, aby można było zrobić prosty katalog.

Przede wszystkim zastanówmy się z czego on się składa? Oczywiście cały samochód jest bardzo skomplikowanym urządzeniem, w związku z tym najlepiej będzie skorzystać z cech paradygmatu programowania obiektowego, gdyż większości informacji nie będziemy potrzebować.

Zasada abstrakcji

Naszym celem jest napisanie aplikacji, która będzie w stanie dostarczyć kilku informacji o samochodach. W związku z tym musimy przyjąć odpowiedni poziom abstrakcji zawężając tym samym liczbę potrzebnych do uwzględnienia części samochodu. Do wykonania wymienionych w zadaniu czynności nie interesują nas takie części jak: wycieraczki, hamulce lub skrzynia biegów, gdyż nie są to informacje, po których przeciętny użytkownik szukałby swojego wymarzonego auta.

Do wykonania naszego zadania wystarczy klasa Samochod. Zwróćmy uwagę, że nazwy klas odpowiadają tym co reprezentują w rzeczywistości i są rzeczownikami.

Klasa Samochód powinna przechowywać informacje o pojemności silnika, typie paliwa, nazwie modelu i marki i rocznik. To są podstawowe dane potrzebne do utworzenia oferty sprzedaży.

Zasada hermetyzacji

W powyższym modelu dostęp do klas zostanie zapewniony przez odpowiednie metody zachowując bardzo ważną zasadę hermetyzacji danych. Metoda getMarka() zwróci nazwę marki auta. Jak widać nazwy metod są czasownikami.

Zwróćmy uwagę, że nie dodamy takiej metody jak setMarka(). Nie będziemy zmieniać podanych wcześniej wartości. Dzięki braku takiej metody mamy pewność, że przez przypadek nie zostanie zmodyfikowana marka samochodu.

W następnej części przyjrzymy się relacjom, które zachodzą miedzy klasami i utworzymy klasy na podstawie naszego powyższego modelu.