Jason. Cała informatyka w jednym miejscu!

Kontynuacja miniserii dziedziczenia w Kotlinie. Skieruję Waszą uwagę na kolejne słowo kluczowe powiązane z dziedziczeniem, a konkretniej z klasami. Przedstawiam Wam "abstract" w języku Kotlin i korzyści płynące z tego, co nam daje programowanie abstrakcji.

"ABSTRACT" W JĘZYKU KOTLIN DZIAŁA TAK SAMO JAK W JAVIE!

To jest dobra wiadomość dla programistów Javy jednak przypomnę dla zasady o co się rozchodzi. Definiowanie abstrakcji w paradygmacie obiektowym pozwala na konstruowanie szkieletu dla klas pochodnych (które stają się "bardziej konkretne"), w sytuacjach kiedy nie da się w żaden sposób określić uniwersalnej implementacji, która stanie się użyteczna dla każdego "następcy". Mało tego, wymusza zdefiniowanie konkretnych wartości lub treści w pierwszej "konkretnej" klasie pochodnej, zatem jeśli klasa pochodna, dziedzicząc po klasie abstrakcyjnej, nie deklaruje się abstrakcyjną, ma obowiązek posiadać implementacje wszystkich abstrakcyjnych właściwości i metod używając słowa kluczowego "override".

KLASA ABSTRAKCYJNA

Abstrakcja dla klasy oznacza zablokowanie możliwości tworzenia obiektów na jej podstawie z powodu zbyt jej ogólnej struktury, aby móc na jej podstawie określić jakiś sens istnienia instancji. Bardzo się to przydaje w celu literalnego zakazania używania konstruktora klasy celem utworzenia obiektu oraz zdefiniowania szkieletu dla pozostałych klas pochodnych, które zostaną zobowiązane do ścisłego określenia wartości (dane składowe) i instrukcji (metody), jeśli nie są abstrakcyjnymi.

Wygląda to tak. Mając przykładową klasę:

class Shape {
	
}

zamieniamy ją na abstrakcyjną przy użyciu słowa "abstract":

abstract class Shape {
	
}

Oznaczenie klasy jako abstrakcyjnej rodzi dwa skutki. Pierwszy, zamykamy możliwość tworzenia obiektów na podstawie tej klasy, czyli ta instrukcja:

val shape = Shape()

skończy się "płaczem" kompilatora i odmówi skompilowania. Drugi, to automatyczne "otwarcie" klasy, czyli "abstract" w języku Kotlin stanowi dwa w jednym. W rzeczywistości to jest "abstract" + "open"!

Aby móc określić samemu kiedy klasa powinna być abstrakcyjną, wystarczy zadać sobie pytanie czy posiada ona dość informacji, aby był sens tworzyć obiekty na jej podstawie. Jeżeli odpowiedź jest twierdząca, to klasa powinna być jedynie otworzona. W przeciwnym razie, ma być abstrakcyjna aby uniemożliwić tworzenie instancji.

WŁAŚCIWOŚĆ ABSTRAKCYJNA

Dana składowa także może być abstrakcyjna i używana z tego samego powodu: kiedy nie jesteśmy w stanie przypisać jej jakiejkolwiek sensownej wartości użytecznej dla każdej klasy pochodnej. Pisząc krótko, dysponując na przykład taką daną składową:

val attribute = [jakaś tam wartość na "odwal się"]

i nie jesteśmy w stanie nadać sensownej wartości dla pozostałych konkretnych klas pochodnych, mamy szansę uczynić ją abstrakcyjną i uniknąć wstawiania byle jakiej, "śmieciowej" wartości:

abstract var attribute: Int

I wtedy nie musimy "zapychać" zmiennej dowolną wartością, żeby dało nam spokój. Właśnie po to stosuje się "abstract" w języku Kotlin (i nie tylko w Kotlinie). Jeśli chodzi o właściwości, to zasady dotyczące właściwości są następujące:

  1. Jeżeli właściwość jest abstrakcyjna, kompilator musi mieć wiedzę o jej typie!
  2. Jeżeli chociaż jedna właściwość jest abstrakcyjna, to cała klasa TAKŻE musi być abstrakcyjna!
  3. Jeżeli w hierarchii dziedziczenia, dana klasa jest pierwszą "konkretną" nieposiadającą znacznika "abstract", to ma obowiązek przesłonięcia wszystkich właściwości abstrakcyjnych (dotyczy to również metod) stosując słowo "override"!

METODA ABSTRAKCYJNA

Oznaczenie metody jako abstrakcyjnej oznacza niemożność jasnego określenia instrukcji dla każdej klasy pochodnej, aby była przydatna dla wszystkich instancji bez względu na okoliczności. Weźmy coś takiego pod lupę:

open fun doSomething() {
	
}

Możemy nie tylko dopuścić do przesłonięcia, ale także i tutaj uniknąć konieczności definiowania pustej nic nierobiącej funkcji dodając tylko jedno słówko:

abstract fun doSomething()

Jaki efekt? Każda klasa pochodna niebędąca abstrakcyjną będzie musiała się opowiedzieć co ma konkretnie robić metoda implementując jej ciało. Uwaga! Tutaj nie wstawiacie ŻADNYCH klamerek! To jest funkcja bez ciała, zatem ma nie mieć śladu klamerek:

abstract fun doSomething() {}

Porównajcie to sobie na spokojnie i dostrzeżcie różnicę samodzielnie.

DODATKOWE CENNE INFORMACJE

Trzeba wiedzieć, że jeśli korzystamy ze słowa "abstract" w języku Kotlin, to nie piszemy dodatkowo że jest otwarta. Ta "otwartość" jest już zawarta w "abstract" i nie musimy tego dopisywać. Abstrakcja już sama w sobie nakazuje z logicznego punktu widzenia, żeby umożliwić przesłanianie, bo w tym wypadku będzie to oznaczało nadanie konkretnych wartości / treści metod w klasach konkretnych. Pamiętajcie również, że jeżeli raz oznaczymy cokolwiek jako abstrakcyjne, to będzie cały czas "wisieć" jako otwarte na przesłanianie dla następnych klas pochodnych, dopóki nie zamkniemy tego słowem kluczowym "final".

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

"abstract" w języku Kotlin czyni klasę, właściwość lub metodę abstrakcyjną, co pozwala wymusić skonkretyzowane zachowanie lub wartość w pierwszej konkretnej klasie pochodnej.


Już wiecie czym jest "abstract" więc zadanie wykonane. W następnej części przedstawię Wam szczegóły następnego słowa kluczowego, "final".

PODOBNE ARTYKUŁY