10.1 Основи поліморфізму
Поліморфізм є однією з ключових концепцій об'єктно-орієнтованого програмування (ООП). У загальному сенсі, поліморфізм дозволяє об'єктам різних класів обробляти дані з використанням одного й того ж інтерфейсу. У контексті JavaScript це означає, що різні об'єкти можуть мати методи з однаковими іменами, і ці методи можуть бути викликані на об'єктах без знання їх конкретного типу.
Типи поліморфізму
У JavaScript основними типами поліморфізму є:
1. Ад-хок поліморфізм (ad-hoc polymorphism):
- Поліморфізм методів, виклик методів з одним і тим самим ім'ям для об'єктів різних типів
- Приклади включають перевантаження функцій і операторів (що не підтримується напряму в JavaScript, але може бути симульовано)
2. Поліморфізм підтипів (Subtype polymorphism):
- Поліморфізм підтипів або включення, коли об'єкти різних класів, які наслідуються від одного й того ж базового класу, можуть оброблятися як об'єкти базового класу
- Це основний тип поліморфізму, реалізований через наслідування та інтерфейси
Переваги поліморфізму:
- Спрощення коду: поліморфізм дозволяє писати більш гнучкий і узагальнений код, який може працювати з різними типами об'єктів, не знаючи їх конкретних типів.
- Розширюваність: поліморфізм спрощує додавання нових типів і поведінки до системи без необхідності змінювати існуючий код.
- Підтримка: поліморфізм сприяє кращому розділенню обов'язків та підвищенню читабельності й підтримки коду.
10.2 Приклади поліморфізму в JavaScript
Поліморфізм підтипів через наслідування
Приклад 1: Обробка різних типів об'єктів за допомогою одного інтерфейсу
У цьому прикладі функція playWithAnimal приймає об'єкт типу Animal і викликає метод makeSound. Об'єкти Dog та Cat, які наслідуються від Animal, перевизначають метод makeSound, і при виклику методу на кожному об'єкті отримується різний результат.
class Animal {
makeSound() {
console.log('Якийсь загальний звук');
}
}
class Dog extends Animal {
makeSound() {
console.log('Гав!');
}
}
class Cat extends Animal {
makeSound() {
console.log('Мяу!');
}
}
function playWithAnimal(animal) {
animal.makeSound();
}
const dog = new Dog();
const cat = new Cat();
playWithAnimal(dog); // Виведе: Гав!
playWithAnimal(cat); // Виведе: Мяу!
10.3 Поліморфізм через інтерфейси (Duck Typing)
У JavaScript немає вбудованої підтримки інтерфейсів, як у інших мовах, таких як TypeScript або Java. Натомість використовується підхід, який називається "утина типізація" (Duck Typing). Це означає, що об'єкт вважається таким, що відповідає інтерфейсу, якщо в нього є необхідні методи й властивості, незалежно від його конкретного типу або наслідування.
Правило качки (duck): якщо щось виглядає як качка, плаває як качка і крякає як качка, то це, ймовірно, і є качка.
Приклад 2: Використання утячої типізації
У цьому прикладі функція takeOff приймає будь-який об'єкт, у якого є метод fly. Об'єкти Bird і Airplane реалізують метод fly, і тому їх можна передати в takeOff.
class Bird {
fly() {
console.log('Лечу...');
}
}
class Airplane {
fly() {
console.log('Реве реактивний двигун...');
}
}
function takeOff(flyingObject) {
flyingObject.fly();
}
const bird = new Bird();
const airplane = new Airplane();
takeOff(bird); // Виведе: Лечу...
takeOff(airplane); // Виведе: Реве реактивний двигун...
10.4 Поліморфізм через функції
У JavaScript функції є об'єктами вищого порядку, і їх можна передавати та використовувати для реалізації поліморфної поведінки.
Приклад 3: Поліморфізм через функції
У цьому прикладі функція greet приймає іншу функцію як аргумент і викликає її. Це дозволяє використовувати різні функції для виконання різних дій.
function greetMorning() {
console.log('Доброго ранку!');
}
function greetEvening() {
console.log('Доброго вечора!');
}
function greet(greetingFunction) {
greetingFunction();
}
greet(greetMorning); // Виведе: Доброго ранку!
greet(greetEvening); // Виведе: Доброго вечора!
10.5 Поліморфізм через перевантаження методу (Симуляція)
JavaScript не підтримує пряме перевантаження методів, як деякі інші мови програмування. Проте, можна симулювати перевантаження методів з використанням аргументів функції та перевірки їх типів.
Приклад 4: Симуляція перевантаження методу
У цьому прикладі метод add приймає два аргументи і виконує різні дії залежно від їх типів. Якщо аргументи — числа, метод їх додає. Якщо аргументи — масиви, метод їх об'єднує.
class Calculator {
add(a, b) {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
} else if (Array.isArray(a) && Array.isArray(b)) {
return a.concat(b);
} else {
throw new Error('Невірні аргументи');
}
}
}
const calc = new Calculator();
console.log(calc.add(1, 2)); // Виведе: 3
console.log(calc.add([1, 2], [3, 4])); // Виведе: [1, 2, 3, 4]
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ