Знаете ли основные принципы объектно-ориентированного программирования
Что проверяют
Знаете ли вы принципы и, что важнее для Go, понимаете ли, что язык реализует их иначе. Пересказ определений из учебника по Java здесь звучит мимо.
Как отвечать
Назовите принципы и сразу покажите, как каждый ложится на Go:
- инкапсуляция есть, но на уровне пакета, а не класса: имя с заглавной буквы экспортируется, со строчной видно только внутри пакета. Инвариант защищается тем, что структура возвращается конструктором и её поля неэкспортируемые;
- абстракция через интерфейсы, причём они выполняются неявно: тип не объявляет, что реализует интерфейс, достаточно совпадения методов. Интерфейс объявляют на стороне потребителя и делают маленьким;
- полиморфизм есть: значение любого типа с нужными методами подходит под интерфейс, а метод вызывается через таблицу;
- наследования нет вовсе, и это принципиальное решение. Вместо него встраивание структур, которое даёт переиспользование без иерархий: методы встроенного типа доступны у внешнего, но это делегирование, а не подстановка.
Сильный ответ добавляет, почему так: наследование связывает классы жёстко и порождает хрупкие иерархии, а композиция и узкие интерфейсы дают ту же гибкость дешевле. В Go нет ни конструкторов как языковой конструкции, ни перегрузки методов, и это тоже осознанный отказ от сложности.
Уместно назвать и практические следствия: зависимости передают интерфейсами, что делает тестирование простым; методы объявляют с указателем или значением осознанно, потому что от этого зависит, увидит ли вызывающий изменения.
Где спотыкаются
Пытаются пересказать наследование применительно к Go и называют встраивание наследованием.
Объявляют интерфейс рядом с реализацией и на каждый тип, получая лишний слой.
Не могут объяснить разницу между методом с указателем и методом со значением.