Jak programować obiektowo? cz. 3 – czym jest metoda?
|
Ostatnio pisałem o elementach struktury obiektów, o tym co je określa i tworzy. Jednak, tak naprawdę z obiektami jest jak w życiu - to nasze czyny nas określają, definiują kim jesteśmy. I to właśnie te zachowania, nasze reakcje są tym, co interesuje naszych znajomych. Czy Sebastian byłby tą samą irytującą osobą, gdyby nazywał się inaczej Zakładając, że w naszych imionach nie tkwi żadna magiczna moc, to zapewne tak.
Nie chcę jednak umniejszać znaczenia wartości atrybutów obiektów, ponieważ często zachowanie jest przez nie uwarunkowane np. jeżeli wiek jest moim atrybutem to jasno widać, że jego wartość ma spory wpływ na wykonywane przeze mnie czynności, na moje reakcje, itp. Dobra, wystarczy już tego odniesienia do rzeczywistości. Rzućmy teraz okiem na metody od strony czysto programistycznej.
Czym jest metoda?
Jak już pisałem wyżej, metody określają to, co „mogą i potrafią” obiekty konkretnej klasy, w jakie interakcje oraz w jaki sposób mogą wchodzić.
Mimo tego, że serię rozpocząłem od artykułu opisującego atrybuty klas, to przy projektach waszych aplikacji radzę zaczynać od metod, od tego co klasy (a właściwie konkretne ich instancje) powinny robić. Wynikową tego i tak będą między innymi atrybuty. Jednak zaczynając od tej strony unikamy nadmiarowości, bo mamy pewność, że trafią do niej (klasy) jedynie te atrybuty, które rzeczywiście są do czegoś nam potrzebne, a nie dodane na zapas, „bo może się przydadzą”. Mam na myśli również klasy domenowe. Wiem, że wielu programistów zaczynając tworzenie nowej aplikacji uważa, że doskonale zdaje sobie sprawę z tego, co siedzi w tych obiektach, bo przecież „są reprezentacją rzeczywistych bytów”, które już owe wartości posiadają.
Oczywiście jest to prawda, niemniej jednak nie każdy z tych atrybutów musi okazać się przydatnym z punktu widzenia implementowanej funkcjonalności. A zawsze łatwiej dodać atrybut gdy okaże się on potrzebny niż usuwać już istniejący. Dlaczego? Jeżeli programista trafia na kawałek kodu, to zakłada, że został on napisany w jakimś celu. A nie zawsze jest możliwość zapytania autora „po co to?”. A niekiedy nawet mając taką możliwość możemy nie uzyskać odpowiedzi.
Czym jest deklaracja/sygnatura metody?
Deklaracje występują jedynie w interfejsach oraz klasach abstrakcyjnych i pełnią tam rolę gwaranta, że metoda o danym API zostanie dostarczona przez klasy, które daną strukturę rozszerzą/zaimplementują. Jeżeli do deklaracji dodamy ciało metody to wtedy już mówimy o sygnaturze metody. W skład deklaracji/sygnatury wchodzą nazwa metody wraz z listą parametrów, które metoda będzie przyjmować oraz typem zwracanym.
Tutaj warto nadmienić, że o ile zmiana nazwy, ilości bądź typu parametrów w deklaracji oznacza stworzenie nowej, to nie jesteśmy w stanie stworzyć dwóch deklaracji różniących się jedynie typem zwracanym. Powód takiego zabiegu jest całkiem prosty - nigdy nie bylibyśmy w stanie stwierdzić, którą metodę w danym momencie wywołujemy, a co za tym idzie - nie bylibyśmy w stanie stwierdzić co dostaniemy w odpowiedzi. Dlatego też przyjmuje się, że metodę jednoznacznie określa jej nazwa oraz parametry.
Ciało i definicja
Dodając do deklaracji ciało (blok z instrukcjami) tworzymy metodę, jej definicję. Dopiero w tym momencie możemy mówić o metodzie. Warto zapamiętać, że wiele definicji może posiadać taką samą deklarację np. wiele klas może implementować ten sam interfejs z licznymi deklaracjami.
Te wszystkie metody, które mamy
Pomimo tego, że z punktu widzenia określenia tego czym metoda jest, powyższe powinno wystarczyć, to omawiając taki temat nie można nie wspomnieć o rodzajach metod. Pod kątem budowy nie różnią się od siebie, jednak każdy rodzaj stosuje się w konkretnych sytuacjach.
- Metody definiujące funkcjonalność - to jest to co nas najbardziej interesuje. Te metody określają zachowanie obiektów, pozwalają na zapewnienie określonych relacji. Tak naprawdę, to gdyby ktoś się uparł, to są jedyne metody, które są nam potrzebne do uszczęśliwienia naszych klientów poprzez dostarczenie działającej aplikacji. To są również jedyne metody niezbędne do tego. Reszta owszem, przydaje się (z biegiem czasu, gdy życie projektu się wydłuża, coraz wyraźniej będziecie to zauważać), ale nie są jednak niezbędne.
- Gettery i settery - są to metody pozwalająca na pobieranie/ustawianie wartości atrybutu obiektu. Od niepamiętnych czasów toczą się zażarte dyskusje na temat tego, czy powinny być stosowane, czy nie i trwają one nadal. Nie chcę rozpoczynać tutaj kolejnej polemiki, jednak ze swojej strony uważam, że z pewnością nadużywanie ich (np. tworzenie zestawu setów i getów dla każdego atrybutu) nie jest zbyt dobrym rozwiązaniem z punktu widzenia projektu. Dodatkowo można zastanawiać się, co w takich przypadkach z enkapsulacją, która jest jednym z paradygmatów programowania obiektowego. Nie uważam jednak, że powinno się zaprzestać ich używania w ogóle, jednak należy to czynić rozsądnie i przede wszystkim świadomie. Jeżeli jakaś metoda jest niezbędna i zdefiniowanie jej jest poprawne z punktu widzenia projektu, to nie należy na siłę implementować innych rozwiązań tylko dlatego, że „gettery i settery są złe”, bo nie są. Złe jest ich błędne używanie.
- Metody specjalne - są to metody, które są wykonywane w określonych przypadkach, bądź cyklach życia obiektu. Zazwyczaj ich wywołanie nie musi się odbywać jawnie, następuje w określonych sytuacjach. Są to m. in. konstruktor, destruktor, clone(), toString().
- Metody abstrakcyjne - tak naprawdę to nie są metody, ponieważ są to jedynie ich deklaracje. Jak już pisałem wyżej, takie konstrukcje wykorzystujemy w interfejsach oraz klasach abstrakcyjnych w celu zapewnienia istnienia konkretnej metody w klasach potomnych.
- Metody statyczne - są to metody, których wywołanie nie wymaga utworzenia obiektów danej klasy, są one powiązane z nią, a nie z jej konkretną instancją.
Metody z punktów trzeciego i czwartego na razie zostawimy, wrócimy do nich jeszcze w późniejszych częściach serii.
I to by było na tyle
Dzisiaj bez kodu, daję wam trochę czasu na przetrawienie tego wszystkiego i poznęcanie się nade mną w komentarzach. Za to obiecuję, że następnym razem będzie tylko kod i postaramy się popatrzyć na przedstawione dzisiaj informacje z tego przyjemniejszego punktu.
Dodatkowo chciałem powiedzieć, że niejedna rzecz, o której dzisiaj pisałem, zostanie dokładniej omówiona w przyszłości, więc jeżeli coś nie jest do końca jasne, to spokojnie, przed nami jeszcze trochę artykułów.
Oczywiście, możecie też po prostu napisać komentarz.
Pozostałe artykuły z cyklu
- Jak programować obiektowo? cz. 9 – klasy abstrakcyjne
- Jak programować obiektowo? cz. 8 – interfejsy
- Jak programować obiektowo? cz. 7 – final
- Jak programować obiektowo? cz. 6 – wartości stałe
- Jak programować obiektowo? cz. 5 – ach ten static…
- Jak programować obiektowo? cz. 4 – metod ciąg dalszy
- Jak programować obiektowo? cz. 3 – czym jest metoda?
- Jak programować obiektowo? cz. 2 – atrybuty klasy
- Jak programować obiektowo? cz. 1 – wstęp