Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чим implements відрізняється від extends у класах?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`extends`** успадковує **реалізацію** і **стан** від батьківського класу ("є різновидом", is-a), а **`implements`** зобов'язує клас **відповідати інтерфейсу (типу)**, але не успадковує код ("відповідає формі", conforms-to). **Ключове:** `extends` - тільки один клас; `implements` - можна кілька інтерфейсів одразу.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Короткий відповідь | Ключове слово | Що робить | Відношення | |---|---|---| | `extends` | Успадковує **реалізацію** і **стан** від батьківського класу | "є різновидом" (is-a) | | `implements` | Зобов'язує клас **відповідати інтерфейсу (типу)**, але не успадковує код | "відповідає формі" (conforms-to) | --- ## 1. `extends` - Успадкування поведінки > Клас з `extends` **успадковує** поля і методи батька. > Може перевизначати (`override`) їх і викликати через `super`. Приклад: ```javascript class Animal { move() { console.log("Animal moves"); } } class Dog extends Animal { bark() { console.log("Woof!"); } } const dog = new Dog(); dog.move(); // успадковано від Animal dog.bark(); // власний метод ``` `Dog` **успадковує реалізацію** з `Animal`. Це означає, що `Dog` *вже вміє* рухатися, не переписуючи метод `move`. --- ## 2. `implements` - Реалізація контракту (інтерфейсу) > Клас з `implements` не отримує нічого "в подарунок". > Він просто **зобов'язаний реалізувати** всі властивості й методи, вказані в інтерфейсі. Приклад: ```javascript interface Logger { log(message: string): void; } class ConsoleLogger implements Logger { log(message: string) { console.log(message); } } const logger = new ConsoleLogger(); logger.log("Hello!"); // реалізовано вручну ``` Тут `Logger` - це **контракт**, а `ConsoleLogger` зобов'язується реалізувати всі його методи. --- ## 3. Головна відмінність в одному реченні - `extends` -> **успадковує реалізацію і стан** (код, поля, методи). - `implements` -> **гарантує наявність** методів і властивостей (контракт), але реалізацію ти пишеш сам. --- ## 4. Можна комбінувати Ти можеш **успадкуватися** від одного класу і **імплементувати** кілька інтерфейсів одночасно: ```javascript interface Swimmer { swim(): void; } interface Runner { run(): void; } class Animal { eat() {} } class Human extends Animal implements Swimmer, Runner { swim() { console.log("Swimming"); } run() { console.log("Running"); } } const person = new Human(); person.eat(); // з Animal person.swim(); // з Swimmer person.run(); // з Runner ``` - `extends` - тільки **один** (клас), - `implements` - **багато** (інтерфейсів). --- ## 5. `extends` для класів vs інтерфейсів TypeScript дозволяє `extends` і **в інтерфейсах** також, але там це працює трохи інакше. | Контекст | Що робить `extends` | |---|---| | У **класах** | Успадковує реалізацію і стан | | В **інтерфейсах** | Об'єднує (успадковує) сигнатури, створює новий тип | Приклад: ```javascript interface A { a: number; } interface B extends A { b: string; } const obj: B = { a: 1, b: "hi" }; // об'єднання властивостей ``` --- ## 6. `implements` не можна використовувати з інтерфейсом усередині інтерфейсу Інтерфейси можуть **розширювати** один одного (`extends`), але не можуть "імплементувати", `implements` призначений **тільки для класів**. ```javascript // Помилка: interface X implements Y {} ``` --- ## 7. Множинне успадкування (і чому воно заборонене) У TypeScript (як і в більшості мов ООП, крім C++) **не можна успадковуватися від кількох класів одразу**, тому що це призводить до конфліктів реалізації. ```javascript class A {} class B {} // Помилка class C extends A, B {} ``` Але можна **імплементувати кілька інтерфейсів**: ```javascript interface X {} interface Y {} class C implements X, Y {} ``` --- ## 8. Реальний приклад: спільний інтерфейс і конкретна реалізація ```javascript interface Repository { save(data: object): void; findById(id: number): object; } class UserRepository implements Repository { save(data: object) { console.log("Saved", data); } findById(id: number) { return { id, name: "Alex" }; } } ``` `UserRepository` *зобов'язаний* реалізувати методи `save` і `findById`, але може реалізувати їх **як завгодно**. --- ## 9. Використання `extends` у класах з `super` ```javascript class Vehicle { constructor(public speed: number) {} move() { console.log(`Moving at ${this.speed} km/h`); } } class Car extends Vehicle { constructor(speed: number, public brand: string) { super(speed); // викликає конструктор Vehicle } move() { super.move(); // викликає метод батька console.log(`${this.brand} is driving`); } } const car = new Car(100, "BMW"); car.move(); // Moving at 100 km/h // BMW is driving ``` `extends` = успадкування поведінки + можливість перевизначення. --- ## 10. Коли використовувати що | Мета | Що обрати | Чому | |---|---|---| | Хочеш перевикористати готовий код (методи, поля) | `extends` | Успадковуєш реалізацію | | Хочеш задати обов'язковий контракт (API, інтерфейс) | `implements` | Клас сам реалізує деталі | | Хочеш зробити спільну форму для кількох інтерфейсів | `extends` (між інтерфейсами) | Об'єднуєш сигнатури | | Хочеш об'єднати поведінку + контракт | `extends` + `implements` | Типово для складних ієрархій | --- ## Підсумок | Ключове слово | Для кого | Що робить | Успадковує реалізацію? | Можна використовувати кілька? | |---|---|---|---|---| | **extends** | класи / інтерфейси | Успадковує поведінку (або сигнатури) | Так (для класів) | Тільки один клас | | **implements** | тільки класи | Перевіряє відповідність інтерфейсу | Ні | Так | --- **Простими словами:** > `extends` - "успадкуй усе, що в нього є". > `implements` - "зроби те саме за формою, але власними руками".Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.