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żeli 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!" :D.

"abstract" w języku Java jest słowem kluczowym czyniącym składową abstrakcyjną. 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żeli klasa dysponuje czymkolwiek abstrakcyjnym, ona sama TEŻ musi być abstrakcyjna,
  2. klasa MOŻE być abstrakcyjna, nawet gdy nie posiada czegokolwiek abstrakcyjnego.

"abstract" w języku Java robi znaczenie gdy kod posiada zbyt mało konkretnych informacji, aby mógł być wykorzystywany. Wtedy taka klasa pozwalająca jedynie na dziedziczenie (a nie tworzenie 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. 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. Przykładem jest klasa "Human", a klasami dziedziczącymi na przykład "Teacher", "Singer" czy też "Actor". 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 dopiero tworzenie obiektów jest zasadne.

Pamiętajcie też o tym, że klasa abstrakcyjna ma prawo 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ę czyni się abstrakcyjną wtedy, 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? Klamerki? Nie ma :O! 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 :D!

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 i lista parametrów mają być takie same. 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.


Mamy za sobą następną część o Javie :).

PODOBNE ARTYKUŁY