Angular - klasy
Stronę tą wyświetlono już: 3516 razy
Podstawy deklaracji klas w TypeScript-cie
Tworzenie klas w czystym JavaScript-cie było dość zabawnym doświadczeniem. Dziedziczenie zaś jeszcze zabawniejszym. A wszystko to dlatego, że w JavaScript-cie obiekty to funkcje. Cóż, w TypeScript-cie jest tak samo tylko, że inaczej. To znaczy w kodzie pisanym przez programistę do utworzenia obiektu klasy używa się słowa kluczowego class, jednakże podczas kompilacji wszystko to jest zamieniane na postać czysto JavaScript-ową. Oto prosty przykład deklaracji klasy w TypeScript-cie:
Tworzenie obiektu klasy Book będzie wyglądało następująco:
Pola i metody klasy domyślnie w TypeScript-cie są dostępne publicznie. Można tworzyć pola i metody, które są typu prywatnego private (dostępne jedynie w obrębie klasy) lub chronione protected (dostępne jedynie w obrębie danej klasy i z poziomu klasy dziedziczącej).
Tak jak w JavaScript-cie tak i w TypeScript-cie konstruktora i metod klasy nie da się przeciążyć jak w innych językach programowania. Można jednakże przekazać do metody klasy argument, będący tablicą różnych typów i w ten sposób rozszerzyć funkcjonalność klasy. Możliwe jest też stosowanie standardowego zastosowania np. zmiennych inicjowanych wartościami domyślnymi np. tak:
Gettery i settery
Warto zapoznać się z możliwością kontroli dostępu do danych z wykorzystaniem getterów i setterów, będących specjalnymi metodami, które mogą być wywoływane tak, jakby były polami klasy. Gettery umożliwiają zwracanie wartości czy to prywatnej, czy to chronionej czy też wyliczanej w locie na podstawie dostępnych w klasie wartości. Settery umożliwiają ustawianie prywatnych i publicznych zmiennych jak również pozwalają na wykonywanie równoczesne szeregu innych operacji, które powinny się wykonać w trakcie ustawiania zmiennych.
Przykład gettera został utworzony już w powyższym przykładzie. Tworzy się go przy użyciu słowa kluczowego get. Getter jest metodą, która nie przyjmuje żadnych wartości a jedynie zwraca wartość. W TypeScript-cie można również podać typ zwracanych danych. Przykładowy getter ma więc postać np. taką:
Wywołanie gettera wyglądać będzie następująco:
Jak widać, choć getter jest funkcją, to wywołuje się go tak, jakby był polem klasy. Takie sztuczne pola klasy nazywane są właściwościami.
Settery w odróżnieniu od getterów nie zwracają żadnej wartości, ale przyjmują jeden argument wykorzystywany do ustawienia innych zmiennych. Załóżmy więc, że mam do stworzenia klasę opisującą prosty twór, jakim jest prostokąt. Prostokąt jak to prostokąt ma pewne właściwości, do których należą: długość boku a; długość przekątnej p no i jeszcze dajmy na to pole powierzchni area. Wszystkie te trzy zmienne są z sobą skorelowane, oznacza to, że zmieniając długość boku a prostokąta zmienia się równocześnie długość przekątnej p oraz pole powierzchni area prostokąta. Do opisu prostokąta użyję tylko jednego pola opisującego długość boku a pozostałe zmienne będą getterami i setterami umożliwiającymi przeliczanie, pobieranie lub ustawianie wartości. Oto przykład:
Przykład utworzenia instancji klasy Square oraz wykorzystanie setterów można zobaczyć poniżej:
Wynikiem działania tego kodu będzie wyświetlenie w konsoli przeglądarki np. Firefoxa lub Chrome następującej treści:
Cechy obiektu prostokąta: Długość boku a: 10 Długość przekątnej b: 14.142135623730951 Pole powierzchni Ppow: 100 Cechy obiektu prostokąta: Długość boku a: 7.071067811865475 Długość przekątnej b: 10 Pole powierzchni Ppow: 49.99999999999999 Cechy obiektu prostokąta: Długość boku a: 3.1622776601683795 Długość przekątnej b: 4.47213595499958 Pole powierzchni Ppow: 10.000000000000002
Implementacja interfejsów w deklaracji klasy
Klasy mogą implementować interfejs, który będzie wymuszał zadeklarowanie w klasie wszystkich wymaganych przez dany interfejs pól i metod. Taką implementację wykorzystują Angular-owe haki do wymuszenia na programiście obsługi z góry określonej metody w celu zapewnienia obsługi określonej funkcjonalności. Taką funkcjonalnością jest np. uruchomienie metody ngOnInit, która przez Angulara będzie wywoływana, gdy dane klasy zostaną zainicjalizowane.
Oto prosty przykład wykorzystania własnego interfejsu do wymuszenia obsługi określonej funkcjonalności:
Dziedziczenie w TypeScript-cie
W TypeScript-cie do dziedziczenia używa się słowa kluczowego extends, które pozwala rozszerzyć daną klasę o funkcjonalności innej klasy lub klas. Oto przykład zastosowania tego mechanizmu:
Przy dziedziczeniu możliwe konieczne jest wywołanie konstruktora klasy bazowej za pomocą funkcji super, która jako argumenty przyjmuje takie same argumenty co sam konstruktor klasy bazowej (czyli w tym przypadku żadne).
Zaletą dziedziczenia jest to, że część kodu zostaje wydzielona do oddzielnej klasy i nadaje się ona do wielokrotnego użytku w wielu innych klasach. Wadą zaś jest to, że klasa bazowa nie może spersonalizować danych w niej związanych w sposób łatwy. To może zrobić jedynie klasa dziedzicząca. Chodzi mi tutaj np o opis jaki może zwracać metoda printTitle: Film pod tytułem: "Tajemnica Andromedy", który w przypadku dziedziczenia jest nie możliwy do zrealizowania w rozsądny sposób. Można jedynie stworzyć tutaj opis typu: Tytuł: "Tajemnica Andromedy" ale czego to jest tytuł to może wiedzieć tylko klasa dziedzicząca.
Klasy abstrakcyjne
W TypeScript klasy abstrakcyjne jak sama nazwa już podpowiada to takie klasy, których obiektów nie da się utworzyć. Potrzebne one są np. do wydzielenia części kodu lub/oraz przechowywania różnych obiektów dziedziczących po tej klasie w jednej tablicy, której typ odpowiada typowi klasy abstrakcyjnej. Sam obiekt klasy tego typu nie może zostać utworzony, ponieważ jego istnienie jest pozbawione sensu. Dla przykładu wszystkie figury płaskie mają takie cechy jak:
- długość obwodu;
- pole powierzchni;
- środek ciężkości;
Lecz każda figura płaska ma inne wzory do obliczania tychże wartości. Utworzenie obiektu figura jest więc mało sensowne, ale utworzenie obiektu klasy np. prostokąt już będzie taki sens miało. Oto przykład deklaracji klasy Shape będąca klasą abstrakcyjną i klasy Square i Circle, które dziedziczą po klasie Shape:
Teraz trochę magii:
Wynik działania powyższego kodu:
Cechy obiektu prostokąta: Długość boku a: 10 Długość przekątnej b: 14.142135623730951 Pole powierzchni Ppow: 100 ============================= Cechy obiektu koła: Promień: 20 Pole powierzchni Ppow: 1256.6370614359173 ============================= Cechy obiektu prostokąta: Długość boku a: 10 Długość przekątnej b: 14.142135623730951 Pole powierzchni Ppow: 100 ============================= Cechy obiektu koła: Promień: 20 Pole powierzchni Ppow: 1256.6370614359173 =============================
Tytuł:
Angular. Profesjonalne techniki programowania. Wydanie IV
Autor:
Adam Freeman
Tytuł:
Angular. Programowanie z użyciem języka TypeScript. Wydanie II
Autor:
Yakov Fain, Anton Moiseev
Tytuł:
ASP.NET Core, Angular i Bootstrap. Kompletny przybornik front-end developera
Autor:
Simone Chiaretta
Tytuł:
Angular instalacja i działanie. Nauka krok po kroku
Autor:
Shyam Seshadri
Tytuł:
Angular w akcji
Autor:
Jeremy Wilken
Tytuł:
ASP.NET Core 2 i Angular 5. Przewodnik dla Full-Stack Web Developera
Autor:
Valerio De Sanctis
Tytuł:
Angular. Profesjonalne techniki programowania. Wydanie II
Autor:
Adam Freeman
Tytuł:
Angular 2. Programowanie z użyciem języka TypeScript
Autor:
Yakov Fain, Anton Moiseev
Tytuł:
Angular 2. Tworzenie interaktywnych aplikacji internetowych
Autor:
Gion Kunz