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('Some generic sound');
}
}
class Dog extends Animal {
makeSound() {
console.log('Woof!');
}
}
class Cat extends Animal {
makeSound() {
console.log('Meow!');
}
}
function playWithAnimal(animal) {
animal.makeSound();
}
const dog = new Dog();
const cat = new Cat();
playWithAnimal(dog); // Выведет: Woof!
playWithAnimal(cat); // Выведет: Meow!
10.3 Полиморфизм через интерфейсы (Duck Typing)
В JavaScript нет встроенной поддержки интерфейсов, как в других языках, таких как TypeScript или Java. Вместо этого используется подход, называемый "утиная типизация" (Duck Typing). Это означает, что объект считается соответствующим интерфейсу, если у него есть необходимые методы и свойства, независимо от его конкретного типа или наследования.
Правило утки (duck): если нечто выглядит как утка, плавает как утка и крякает как утка, то это, вероятно, и есть утка.
Пример 2: Использование утиной типизации
В этом примере функция takeOff принимает любой объект, у которого есть метод fly. Объекты Bird и Airplane реализуют метод fly, и поэтому их можно передать в takeOff.
class Bird {
fly() {
console.log('Flying...');
}
}
class Airplane {
fly() {
console.log('Jet engine roaring...');
}
}
function takeOff(flyingObject) {
flyingObject.fly();
}
const bird = new Bird();
const airplane = new Airplane();
takeOff(bird); // Выведет: Flying...
takeOff(airplane); // Выведет: Jet engine roaring...
10.4 Полиморфизм через функции
В JavaScript функции являются первоклассными объектами, и их можно передавать и использовать для реализации полиморфного поведения.
Пример 3: Полиморфизм через функции
В этом примере функция greet принимает другую функцию в качестве аргумента и вызывает ее. Это позволяет использовать различные функции для выполнения различных действий.
function greetMorning() {
console.log('Good morning!');
}
function greetEvening() {
console.log('Good evening!');
}
function greet(greetingFunction) {
greetingFunction();
}
greet(greetMorning); // Выведет: Good morning!
greet(greetEvening); // Выведет: Good evening!
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('Invalid arguments');
}
}
}
const calc = new Calculator();
console.log(calc.add(1, 2)); // Выведет: 3
console.log(calc.add([1, 2], [3, 4])); // Выведет: [1, 2, 3, 4]
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ