Какие базовые принципы ООП: абстракция, наследование, инкапсуляция, полиморфизм
Что проверяют
Не заучены ли четыре слова, а понимаете ли, как принципы выглядят именно в Python, где нет модификаторов доступа и работает утиная типизация. Следом уточняют, чем Protocol отличается от абстрактного класса и когда наследование стоит заменить композицией.
Как отвечать
По каждому принципу давайте определение и питоновскую реализацию:
- абстракция: выделяем контракт и прячем детали.
abc.ABCс@abstractmethodне даст создать экземпляр без реализации, наследование явное.typing.Protocol(PEP 544) задаёт структурный контракт: класс подходит, если у него есть нужные методы, наследоваться не требуется; - инкапсуляция: держится на соглашениях. Одно подчёркивание
_xозначает «внутреннее», два__xвключают искажение имени в_Class__x, и это защита от коллизий в наследниках, а не от доступа. Публичный интерфейс поверх поля даёт@property,__slots__фиксирует набор атрибутов,@dataclass(frozen=True)делает объект неизменяемым; - наследование: множественное, порядок разрешения методов считается алгоритмом C3 и виден в
Class.__mro__.super()идёт по MRO, а не «к родителю», поэтому кооперативные миксины работают, только если каждое звено вызываетsuper(); - полиморфизм: опирается на утиную типизацию и протокол объекта (
__len__,__iter__,__eq__), а не на общий базовый класс. Диспетчеризация по типу первого аргумента есть вfunctools.singledispatch.
Сильный ответ добавляет границы. Наследование жёстко связывает классы, композиция и передача зависимости в конструктор обычно гибче. Подкласс не должен ломать поведение базового типа (принцип Лисков), иначе полиморфизм превращается в набор проверок isinstance.
Где спотыкаются
Утверждают, что __x это приватное поле. Атрибут доступен как obj._Class__x: приватности в языке нет, есть договорённость.
Строят иерархию на пять уровней ради пары методов, а потом не могут объяснить, откуда взялась реализация в конкретном экземпляре: MRO никогда не смотрели.
Путают перегрузку и переопределение. Перегрузки по сигнатуре в Python нет: второе определение метода затирает первое, а декоратор @overload из typing влияет только на проверку типов.