Zawrót głowy w Scali: class, trait, object, instancja

namiekko.pl 5 lat temu

Fajne rzeczy w Scali: klasy przypadkówKiedy jako programista Javy po raz pierwszy ujrzałam kod napisany w Scali, miałam spore problemy ze zrozumieniem, czym różnią się od siebie poszczególne byty:

  • class (klasa)
  • case class (klasa przypadków)
  • trait (cecha)
  • object (obiekt)
  • instancje klas (bo “obiekt” w Scali to wcale nie jest instancja!).

Poniżej ściąga dla zainteresowanych i dla przyszłej mnie

Klasa

Klasa (class) jak w przypadku większości obiektowych języków programowania, to szablon, na podstawie którego można tworzyć ukonkretnione instancje. Zawiera pola i metody. Ponieważ Scala jest językiem funkcyjnym, dobrym zwyczajem jest tworzenie klas niemodyfikowalnych.

Klasa przypadków

O klasach przypadków (case class) więcej napisałam tutaj: Fajne rzeczy w Scali: klasy przypadków. Klasy przypadków to specjalne klasy, których instancje można porównywać przez wartość i dopasowywać do wzorców w ramach instrukcji match.

Cecha

Cechy (trait) są podobne do klas i umożliwiają wielokrotne dziedziczenie (które ostatecznie i tak jest linearyzowane przez kompilator, ale nie o tym teraz). Różne byty (klasy, obiekty, cechy) w Scali mogą rozszerzać jedną tylko klasę, ale za to wiele cech.

Przy dziedziczeniu z kilku cech trzeba użyć słowa kluczowego with:

class K extends A with B with C

Jeśli wśród “rodziców” znajduje się jakaś klasa, musi ona zostać wymieniona pierwsza, zaraz po słowie extends.

Nie można tworzyć instancji cech.

Cechy można dodawać do klas na etapie ich definicji, ale także do instancji na etapie ich tworzenia. Cechę można dorzucić do adekwatnie każdej klasy – chyba iż ograniczymy listę dozwolonych typów przy użyciu słowa kluczowego self (co ma sens np. jeżeli kod którejś z metod odwołuje się do pola istniejącego tylko w danej hierarchii klas).

Obiekt

Obiekt (object) w Scali to klasa, która może miec maksymalnie jedną instancję – a więc, innymi słowy, singleton. Instancja ta zostanie utworzona w momencie pierwszego dostępu do niej przez JVM. Obiekty umożliwiają tworzenie odpowiedników metod i pól statycznych (globalnych), tj. atrybutów niepowiązanych z konkretną instancją klasy.

Obiekt może dziedziczyć z jakiejś klasy albo cechy.

Często stosowanym wzorcem w Scali są obiekty towarzyszące. Obiekt towarzyszący ma taką samą nazwę jak klasa, jest definiowany w tym samym pliku i ma (z wzajemnością) dostęp do jej prywatnych pól i metod. Obiekty towarzyszące mogą pełnić funkcję fabryki instancji danej klasy.

Kolejne zastosowanie obiektów to aplikacje w linii poleceń. Wewnątrz obiektu można zdefiniować metodę main, która zostanie uruchomiona po wywołaniu kodu z linii poleceń.

object Hello { def main(args: Array[String]) { println("Hello, World!") } }

Instancja

Instancja to instancja czyli konkretny jeden byt stworzony w oparciu o wzór opisany w ramach klasy.

Przyznam, iż w mojej własnej głowie nietypowe użycie słowa object narobiło sporo zamieszania. Podejrzewam, iż w miarę poznawania języka zrozumiem, dlaczego tak się stało i przestanie mnie to zaskakiwać.

Gdzie znaleźć więcej szczegółów?

Oto kilka źródeł dogłębniej tłumaczących omawiane to różnice:

Idź do oryginalnego materiału