Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос нашим менторам. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете
JS: Полиморфизм

Код, который убивает полиморфизм

Формирование объектов

Посмотрите на функцию ниже и скажите, является ли она полиморфной?

const sayHiByEmail = (user) => {
  const sender = new EmailSender();
  // Отправляем email пользователю
  sender.send(user.getEmail(), 'hi!');
};

С одной стороны да, пользователь передаётся снаружи и у нас есть возможность его подменить, передав туда объект другого класса. С другой стороны, внутри функции явно используется класс EmailSender и его подменить не получится без переписывания самого кода.

Этот код демонстрирует простую, но важную идею. Полиморфизм подтипов возможен тогда, когда объект попадает в функцию снаружи, а не конструируется прямо внутри неё.

Честно говоря, объект можно создавать и внутри функции, но в таком случае имя класса должно формироваться (или получаться) динамически. Этот приём мы рассмотрим позже, в уроке про метапрограммирование.

Проверка типов

Ещё один пример с подвохом. Есть ли полиморфизм в коде ниже?

const sayHi = (user) => {
  if (user instanceof User) {
    console.log(`Hello, ${user}!`);
  } else if (user instanceof Guest) {
    console.log('Hello, guest!');
  } else {
    console.log('Who are you?');
  }
};

В данном примере, вроде бы, всё нормально, объект передаётся снаружи, но есть одна загвоздка. Внутри функции явно проверяется тип, а это значит, что поведение определяется не типом, а сама функция решает как себя вести. Более того, функция жёстко связана с теми типами, которые определены внутри неё и её придётся переписывать при их изменении. И как результат – отсутствие полиморфизма подтипов.

Проверка типа иногда встречается и её можно использовать к месту, чтобы не усложнять код, но чаще, она говорит о плохом дизайне. Такой код, можно сказать, не соответствует ООП в современном его понимании.

Для решения задачи выше, есть несколько подходов:

  • Перенос логики внутрь самих классов. Тогда код функции превратится в такой: user.sayHi(). С этим подходом нужно быть осторожным, так как легко получить божественный объект. Гораздо чаще нужно применять другой подход.

  • Понадобится добавить новый интерфейс в виде методов isUser и isGuest.

    const sayHi = (user) => {
      if (user.isUser()) {
        console.log(`Hello, ${user}!`);
      } else if (user.isGuest()) {
        console.log('Hello, guest!');
      } else {
        console.log('Who you are?');
      }
    };
    

    И хотя кода меньше не стало, всё же это полиморфизм подтипов. Код завязан на методы, а не на типы. Изменение структуры классов не коснётся этой функции, если сама логика останется той же.


<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят менторы из команды Хекслета или другие студенты.

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, даст возможность обращаться за помощью к менторам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Зарегистрироваться

или войти в аккаунт

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».