Класи та інтерфейси
Класи
Конструктор
Конструктор класу є спеціальним методом, який використовується для ініціалізації нового об'єкта класу. Конструктор дозволяє встановити значення властивостей об'єкта при його створенні.
У цьому прикладі constructor(name: string) - це конструктор класу Person, який приймає рядок param як параметр і ініціалізує властивість name об'єкта класу з переданим значенням.
Коли ви створюєте новий об'єкт класу за допомогою оператора new, конструктор викликається автоматично, і ви можете передавати параметри конструктору для налаштування початкового стану об'єкта.
Методи
Метод класу - це функція, яка визначена в тілі класу і пов'язана з об'єктами, які створюються на основі цього класу. Метод класу використовується для визначення поведінки об'єктів даного класу.
Додамо до прикладу вказаного вище якісь методи. Один нехай повертає значення (яке ми покажемо через консоль), а другий формує і виводить повідомлення одразу.
І ось, що ми побачимо в консолі.
Ключове слово this - це посилання на контекст виконання. А оскільки наші методи будуть всередині створених обʼєктів на основі цього класу, то this.name - це посилання на властивість name всередині створеного обʼєкта.
Метод вашого класу можна скопіювати в який новий обʼєкт. допишемо до вищевказаного коду такі рядки. І подивимося, що покажеться у консолі.
Як бачимо, в новий обʼєкт метод ми скопіювали, але сам параметр не задали. Тобто не задали контекст. Трохи доповнимо код:
Модифікатори доступу
Модифікатори доступу - це ключові слова, які використовуються для визначення видимості класів, властивостей і методів в межах програми. Ці модифікатори вказують, які частини класу можуть бути доступні ззовні класу або обмежені в межах самого класу.
В TypeScript є три основні модифікатори доступу:
public - це як всі властивості та методи в js, можна викликати будь-де
private - не можна викликати ззовні екземпляра, не наслідується
protected - не можна викликати ззовні екземпляра, але наслідується
Public (public): Якщо ви використовуєте public перед властивістю чи методом, це означає, що вони доступні ззовні класу.
Private (private): Якщо ви використовуєте private перед властивістю чи методом, це означає, що вони доступні лише всередині самого класу. Вони не можуть бути доступні або змінені ззовні класу.
Protected (protected): Якщо ви використовуєте protected перед властивістю чи методом, вони доступні в самому класі та в похідних класах. Це дозволяє спадкоємцям класу користуватися цими частинами класу, але не дозволяє зовнішнім об'єктам отримати до них доступ.
Тобто, треба використовувати public - коли це інтерфейс взаємодії, private - коли це технічні методи або властивості, які не варто викликати поза класом, protected - коли це технічні методи або властивості, які не варто викликати поза, але при цьому вони повинні наслідуватися дочірніми.
Роблячи властивість приватною або захищеною ми уберігаємо її від прямої зміни. Для цього передбачають спеціальні методи для роботи зміни не на пряму. Наприклад:
У такому разі нам видасть помилку, якщо ми захочемо напряму змінити приватну властивість someMsg
Таким чином ми змушуємо розробників користуватися визначеними відкритими методами для зміни властивостей.
Скорочення ініціалізації
Як ми дотепер описували конструктор для створення обʼєктів на основі класу.
Але у TypeScript існує зручний спосіб скороченої ініціалізації властивостей класу через конструктор. Цей підхід дозволяє визначити властивості класу прямо в параметрах конструктора.
У цьому прикладі конструктор класу Person має два параметри (firstName і lastName), які одразу використовуються для ініціалізації приватних властивостей firstName і lastName. Це зручний підхід, який дозволяє визначити властивості класу та їхні значення в одному місці. При цьому ви не потребуєте додаткових рядків коду для присвоєння значень властивостям в тілі конструктора.
Readonly
Ключове слово readonly використовується для вказання, що властивість класу може бути прочитана, але не може бути змінена після її ініціалізації. Це робить властивість "тільки для читання".
У цьому прикладі radius є властивістю класу Circle, і вона є readonly. Це означає, що після того, як значення radius встановлено у конструкторі, воно не може бути змінено в інших частинах класу або ззовні. Якщо ви спробуєте змінити значення radius поза конструктором або в інших методах класу, компілятор TypeScript виділить помилку. Це допомагає захистити дані від непередбачених змін.
Зазначте, що readonly можна використовувати не тільки для властивостей класів, але і для властивостей інших об'єктів в TypeScript.
Наслідування
У TypeScript, як і в інших об'єктно-орієнтованих мовах програмування, наслідування дозволяє одному класу (підкласу) успадковувати властивості і методи іншого класу (базового класу). Це означає, що підклас може використовувати властивості і методи базового класу, а також визначати власні властивості і методи.
Для створення успадкування в TypeScript використовується ключове слово extends.
У цьому прикладі клас Dog успадковує властивості та методи класу Animal. Ключове слово super використовується для виклику конструктора базового класу та доступу до його методів та властивостей (його потрібно викликати до будь-якої маніпуляції з this в конструкторі).
Успадкування дозволяє створювати ієрархії класів, де підкласи можуть розширювати або перевизначати поведінку базових класів в залежності від власних потреб.
Getter/Setter
Getter і Setter - це спеціальні методи класу в TypeScript (і в інших об'єктно-орієнтованих мовах програмування), які дозволяють отримувати (читати) та встановлювати (змінювати) значення властивостей об'єкта, відповідно. Це дозволяє контролювати доступ до властивостей і виконувати додаткові операції при їхньому зчитуванні або встановленні.
У TypeScript ви можете використовувати ключові слова get і set для визначення Getter і Setter, відповідно.
Синтаксис такий, ніби ми звертаємося до властивості, але по факту запускаються методи, які обробляють ці дані.
Статичні методи та властивості
Статичні методи та властивості в TypeScript належать не конкретному екземпляру класу, а самому класу. Це означає, що їх можна викликати або використовувати без створення об'єкта класу. Вони корисні, коли ви хочете виконати операції, які не пов'язані з конкретним екземпляром класу, або коли вам потрібно зберігати значення, які відносяться до самого класу, а не до його екземплярів.
Щоб створити властивість або метод статичним, просто після модифікатора вказуємо static.
Статичні методи
У цьому прикладі multiply - це статичний метод класу MathOperations. Його можна викликати без створення об'єкта класу.
Статичні властивості
Статичні властивості працюють аналогічно статичним методам, але вони представляють собою значення, які відносяться до самого класу, а не до його екземплярів.
Абстрактні класи та методи
Абстрактні класи та методи в дозволяють визначити структуру класу, але не надають конкретну реалізацію для деяких частин цього класу. Абстрактні класи створюються за допомогою ключового слова abstract. Абстрактний метод - це метод, який визначається в абстрактному класі, але не має тіла (реалізації). Абстрактний клас може мати як абстрактні методи, так і звичайні методи з реалізацією.
Абстрактні класи
У цьому прикладі Shape - це абстрактний клас, який має абстрактний метод calculateArea(). Клас Circle успадковує абстрактний клас Shape і реалізує його абстрактний метод.
Абстрактні методи
Абстрактний метод - це метод без реалізації, який визначений в абстрактному класі і повинен бути реалізований в його похідних класах. Абстрактні методи позначаються ключовим словом abstract перед їхнім визначенням.
У цьому прикладі Animal - це абстрактний клас з абстрактним методом makeSound(). Клас Dog успадковує Animal і реалізує його абстрактний метод.
Це дає нам контроль над реалізацією дочірніх класів, доки ми не реалізуємо свій метод у кожному з класів, то отримуватимемо помилку, і ми даємо гарантію, що у кожному дочірньому класі буде своя реалізація.
Інтерфейси
Інтерфейси - це спосіб визначення контракту для об'єктів. Вони використовуються для опису структури об'єктів та визначення, які властивості або методи повинні бути присутніми у класі або об'єкті, який реалізує цей інтерфейс. Чимось сзоді на абстрактні класи, от тільки зовсім не описують реалізацію, а тільки містять структуру.
Інтерфейси об'єктів
Інтерфейси об'єктів в TypeScript використовуються для визначення структури об'єктів. Вони визначають набір властивостей та їхні типи, які повинні бути присутніми в об'єкті, який реалізує цей інтерфейс. Це дозволяє вам створювати загальні конструкції для об'єктів та забезпечувати типовий контракт для їхньої структури.
Інтерфейс описують після ключового слова interface. Назви інтерфейсам дають з великої літери. Тут інтерфейс працює як тип - він просто показує, які поля повинні бути в об'єкті.
Якщо об'єкт не має всіх властивостей, вказаних в інтерфейсі, TypeScript видасть помилку.
При роботі з обʼєктами інтерфейс можна записати як тип і функціонад буде такий само.
Інтерфейси класів
Інтерфейси класів в TypeScript дозволяють визначити контракт для класів. Вони описують структуру класів, вказуючи наявність конкретних властивостей та методів, які повинні бути присутніми у класі, що реалізує інтерфейс. Інтерфейс класу виглядає аналогічно інтерфейсу об'єктів, але описує структуру класу замість структури об'єктів.
Підключення інтерфейсів відбувається через команду implements і далі через кому ми передаємо будь-яку кількість інтерфейсів. А у класі будують логіку на цьому інтерфейсі.
Але сам клас ми можемо розширювати, додаючи йому нові методи та властивості (яких. немає в інтерфейсах), у цьому інтерфейси нас не обмежують. Наприклад можна ініціалізувати додаткову властивість, або описати додатковий метод.
Readonly
В інтерфейсі не можна задавати модифікатори private, protected, оскільки вони всі вважаються як public (щоб можна було вказати private - для цього є абстрактний клас).
Але ми можемо задати readonly.
Розширення інтерфейсів
Можна розширювати інтерфейси за допомогою команди extends
Інтерфейси як тип функції
Замість типу функції її можна описати інтерфейсом. Функціонал один і той самий. Який вибрати - на вибір розробника.
Опціональні параметри
В Інтерфейсах також можна використовувати опціональні параметри. Потрібно тільки вказати ? перед зазначенням типу.
Last updated