Jason. Cała informatyka w jednym miejscu!

Oto kolejny materiał dotyczący Javy jakim jest słowo kluczowe "abstract" w języku Java. Poprzednio wprowadziłem Was w dziedziczenie, a teraz zapoznacie się z kolejnym elementem, który bądź co bądź może wydawać się jedynie "dekoracją", aczkolwiek stanowi ważny wątek podnoszący elastyczność naszej aplikacji. Dowiecie się co to jest klasa i metoda abstrakcyjna, czym się one różnią od "zwykłych" odpowiedników oraz jaki to ma wpływ na przebieg pisania kodu.

"ABSTRACT" W JĘZYKU JAVA KOLEJNYM MODYFIKATOREM

Trzeba wpierw sobie wytłumaczyć czym jest abstrakcja. Jest to jeden z czterech najważniejszych postulatów programowania obiektowego, który mówi o tym, że jeśli nie da się określić w żaden sposób ogólnego wzorca dla danej składowej lub metody, to powinna być abstrakcyjna, a jej implementacja wymuszana we wszystkich klasach potomnych, jeśli one same nie są abstrakcyjne. Wymuszana, czyli "albo zrobisz co Ci każę, albo nici z kompilacji!".

Słowo kluczowe czyniące daną abstrakcyjną to "abstract" w języku Java. Musimy od tej pory podzielić materiał na dwie sekcje. Zademonstruję klasę i metodę abstrakcyjną w podanej kolejności.

KLASA ABSTRAKCYJNA

Odwołując się do tego samego przykładu w poprzednim artykule, mieliśmy klasę "BaseClass", która była klasą bazową klasy "ChildClass". To przypuśćmy, że teraz "BaseClass" stanie się klasą abstrakcyjną:

abstract class BaseClass {

}

Spowoduje to dwie rzeczy:

  1. utworzenie instancji klasy "BaseClass" stanie się niemożliwe
  2. WSZELKIE dane abstrakcyjne będą musiały otrzymać jasną definicję ze strony KAŻDEJ klasy potomnej (chyba, że ona też będzie abstrakcyjną)

Jeszcze na dokładkę zasada odnośnie wymagalności:

  1. jeśli klasa dysponuje czymkolwiek abstrakcyjnym, ona sama TEŻ musi abstrakcyjna
  2. klasa MOŻE być abstrakcyjna, nawet gdy nie posiada czegokolwiek abstrakcyjnego

Jak napisałem na początku, to tak naprawdę jest jedynie dbałość o szczegół i jest to traktowane całkowicie opcjonalnie, bo program od tego się nie wysypie ani świat nie wyginie (choć byłoby wysoce wskazane), aczkolwiek "abstract" w języku Java zaczyna robić większe znaczenie gdy ten sam kod ma być później wykorzystywany przez kogoś innego. Wtedy taka klasa pozwalająca jedynie na dziedziczenie a nie tworzenia obiektów na jej podstawie, może oszczędzić pewnych problemów i uchronić przed konsekwencjami wynikającymi z korzystania ze zbyt ogólnych obiektów.

W przeważającej większości przypadków drzewo dziedziczenia tak się konstruuje, że "korzeń" stanowi jedynie szkielet samych czynników ogólnych i posiada za mało informacji, aby na jego podstawie tworzyć obiekty zachowując przy tym sens projektowy. Dlatego też, taka klasa powinna być klasą "abstrakcyjną". Sygnalizujemy przez to kompilatorowi, że dana klasa jest zbyt ogólna, aby był sens tworzenia obiektów w oparciu o jej (niekompletne) dane składowe i metody. To właściwie jest jedyna moja porada kiedy to umieszczać. Kiedy jesteście pewni, że dana klasa nie dostarcza wystarczającej ilości informacji, aby obiekt tego typu stał się samodzielnym bytem. Innym przykładem mogłaby być klasa "Human", a klasami dziedziczącymi na przykład "Teacher", "Singer" czy też "Actor". Rozumiecie? Każdy z nas jest człowiekiem, ale to jest za ogólne stwierdzenie. Musi być jeszcze jakiś bardziej szczegółowy "filtr" i to może być na przykład podział na zawody. Wtedy dziedziczenie w języku Java ma ręce i nogi.

Pamiętajcie też o tym, że klasa abstrakcyjna ma prawo nadal mieć konstruktor! Pomyślicie pewnie "Co? Nie mogę tworzyć obiektów, a mimo tego jest konstruktor?". Ano jest! Gdyby ktoś szukał odpowiedzi czemu to miałoby służyć, proponuję poczytać o słowie kluczowym "super" i o odwołaniu do klasy bazowej.

METODA ABSTRAKCYJNA

Druga część - metoda abstrakcyjna. Metodę radzę dać abstrakcyjną, kiedy nie ma żadnej możliwości zaimplementowania instrukcji, które będą pasować dla wszystkich klas potomnych. Dajmy na to, że do "BaseClass" sobie wstawimy taką metodę:

abstract class BaseClass {
	public abstract void doSomething();
}

Czy widzicie coś innego? Nie? A ciało metody? A klamerki? Nie ma! I nie wstawiamy ich nigdy w życiu kiedy mowa o abstrakcyjnej metodzie!!! Umieszczamy natomiast średnik! "abstract" w języku Java nakazuje metodzie umieścić średnik zamiast pary klamerek. To dotknie na swój sposób również klasy potomne - wszystkie z nich mają obowiązek posiadać własną implementację tejże metody. A po polsku? Przesłanianie!

class ChildClass extends BaseClass {
	@Override
	public void doSomething() {
		// instrukcje
	}
}

Przypominam o zachowaniu spójności pomiędzy nagłówkiem metody, a jej implementacją. Typ zwracanej wartości ma być taki sam i lista parametrów formalnych taka sama. Przykładem użycia może być klasa pracownika, która posiada metodę polegającą na wykonywaniu przez niego czynności w godzinach pracy. Jakie można dać ogólnie pasujące obowiązki do wykonania? Sprzątacz będzie zamiatać schody, nauczyciel uczyć dzieci, a dziennikarz gromadzić materiały na artykuł w gazecie. Nie da się zdefiniować jakiegokolwiek zajęcia uniwersalnego, które pasowałoby do każdego stanowiska!

ZMIENNA (DANA SKŁADOWA) ABSTRAKCYJNA

Ostatnia część dotyczy danych składowych, czyli zmiennych abstrakcyjnych. Gdyby ktoś się zastanawiał jak można...to nie można! Java nie wspiera definiowania abstrakcyjnych danych składowych!

Słowo kluczowe "abstract" w języku Java

Słowo kluczowe "abstract" w języku Java informuje kompilator, że dana klasa jest "zbyt ogólna", aby był sens tworzyć obiekty na jej podstawie, a w stosunku do metod oznacza brak możliwości zdefiniowania ogólnego wzorca dla wszystkich klas potomnych.


Kolejną część mamy za sobą, tutaj znajduje się dalszy ciąg...

PODOBNE ARTYKUŁY