Что такое полиморфизм в ООП?

Ответ

Полиморфизм — это принцип объектно-ориентированного программирования, позволяющий объектам с разной внутренней реализацией обрабатываться через единый интерфейс. В контексте Node.js и JavaScript/TypeScript это реализуется несколькими способами:

  1. Переопределение методов (динамический полиморфизм): Дочерний класс может переопределить метод родительского класса.

    class Logger {
      log(message) {
        console.log(`[LOG]: ${message}`);
      }
    }
    
    class FileLogger extends Logger {
      log(message) {
        // Переопределение: логирование в файл вместо консоли
        const fs = require('fs');
        fs.appendFileSync('app.log', `${message}n`);
      }
    }
    
    const logger = new FileLogger();
    logger.log('User logged in'); // Вызовется метод FileLogger.log
  2. Полиморфизм на основе интерфейсов (в TypeScript): Разные классы, реализующие один интерфейс, могут использоваться взаимозаменяемо.

    interface DataStorage {
      save(data: string): void;
    }
    
    class DatabaseStorage implements DataStorage {
      save(data: string) {
        // Логика сохранения в БД, например, с использованием Prisma или Mongoose
        console.log(`Saving to DB: ${data}`);
      }
    }
    
    class CloudStorage implements DataStorage {
      save(data: string) {
        // Логика отправки в облако (AWS S3, Google Cloud Storage)
        console.log(`Uploading to cloud: ${data}`);
      }
    }
    
    function processData(storage: DataStorage, data: string) {
      // Функция работает с любым объектом, реализующим DataStorage
      storage.save(data);
    }
    
    processData(new DatabaseStorage(), 'record1');
    processData(new CloudStorage(), 'record2');

Практическая польза в Node.js: Полиморфизм позволяет создавать гибкие и расширяемые системы, например, подключать разные стратегии кэширования (Redis, Memcached, in-memory), различные провайдеры аутентификации или адаптеры для баз данных через единый контракт, что упрощает тестирование и поддержку.

Ответ 18+ 🔞

А, полиморфизм! Ну это, ёпта, такая штука, когда ты можешь одной и той же командой заставить разные объекты делать своё, но по-своему. Представь, как будто ты кричишь «принеси пива!» — один сгоняет в магазин, другой откроет холодильник, третий начнёт варить своё, но в итоге пиво-то будет. Все принесли, но способ — овердохуища разный.

Вот смотри, в Node.js и TypeScript это выглядит примерно так.

Первый способ — переопределение методов. Это когда сынок думает, что он умнее папаши, и делает всё по-своему, но название команды то же самое.

class Logger {
  log(message) {
    console.log(`[LOG]: ${message}`);
  }
}

class FileLogger extends Logger {
  log(message) {
    // А вот тут сынок-перепиндюй говорит: "Папа, иди на хуй, я буду в файл писать!"
    const fs = require('fs');
    fs.appendFileSync('app.log', `${message}n`);
  }
}

const logger = new FileLogger();
logger.log('User logged in'); // Вызовется уже не папин метод, а сыночка-бунтаря

То есть ты вызываешь log, а там внутри уже полная хитрая жопа — не в консоль, а в файл. Но тебе-то похуй, ты команду дал и получил результат.

Второй способ — через интерфейсы в TypeScript. Это вообще красота, ядрёна вошь. Ты говоришь: «вот вам всем договор — у вас должен быть метод save». А кто как его реализует — это уже их личные проблемы, хоть в облако, хоть в соседнюю папку.

interface DataStorage {
  save(data: string): void;
}

class DatabaseStorage implements DataStorage {
  save(data: string) {
    // Этот чувак лезет в базу данных, как будто в карман за ключами
    console.log(`Saving to DB: ${data}`);
  }
}

class CloudStorage implements DataStorage {
  save(data: string) {
    // А этот уже швыряет данные куда-то в интернеты, хоть на марс
    console.log(`Uploading to cloud: ${data}`);
  }
}

function processData(storage: DataStorage, data: string) {
  // А вот тут магия: этой функции похуй, кто перед ней. Главное, чтобы метод save был.
  // Она как тот начальник, который орет "работай!", а ты уж сам решай, как.
  storage.save(data);
}

processData(new DatabaseStorage(), 'record1'); // Полетело в БД
processData(new CloudStorage(), 'record2'); // Улетело в облака

А зачем это всё в Node.js, спрашиваешь? Да чтобы жизнь мёдом не казалась, а казалась гибкой и расширяемой! Допустим, у тебя кэш. Сегодня ты используешь Redis, а завтра начальство скажет: «Бля, Redis дорогой, давайте на Memcached переедем». Если ты через полиморфизм сделал, то тебе просто нужно нового «исполнителя» написать, который тоже умеет get и set. Вся остальная система даже не заметит подмены — доверия ебать ноль, но работает. То же самое с аутентификацией: через GitHub, через Google, через какого-нибудь пидараса шерстяного из Active Directory — интерфейс один, а реализация разная. Тестировать это удовольствие, потому что можно подсунуть «заглушку» и не париться.

Короче, полиморфизм — это когда ты управляешь разными сущностями через одну команду, а они уже сами решают, как им впиздюрить результат. Удобно, гибко, и если что-то сломается — виноват конкретный исполнитель, а не вся система. В рот меня чих-пых, хорошая штука.

Видео-ответы