Принципы ООП

Принцип - в переводе с греческого “первейшее” это утверждение на основе которого создаются законы.

Абстракция

подробнее

Абстракция — это процесс скрытия сложной реализации за простым интерфейсом. Она позволяет сосредоточиться на важных аспектах объекта, игнорируя ненужные детали.

Абстрактный класс

подробнее

Абстрактный класс - это шаблон для классов наследников. Из него нельзя создать экземпляр класса и он содержит абстрактные методы (не имеющие реализации.). Кроме того он может содержать обычные методы.

Интерфейс

подробнее

Интерфейс — это контракт или спецификация, которая определяет какие методы должен реализовать класс, без предоставления реализации. Это “обещание” о том, что класс будет иметь определенное поведение.
Так же как и абстрактный класс это шаблон для классов наследников, из него нельзя создать экземпляр класса и он содержит абстрактные методы. Но обычные методы он не может содержать.

Разница между интерфейсом и абстрактным классом:

Характеристика Интерфейс Абстрактный класс
Методы Только абстрактные Абстрактные + конкретные
Атрибуты Обычно нет Может содержать
Наследование Множественное Одиночное
Цель Определить контракт Частичная реализация + контракт

Наследование

подробнее

Наследование - это принцип, который говорит о том что класс наследник расширяет класс родителя.
У наследника появляются свои аттрибуты и методы в дополнение к родителю.
Также наследник может переопределить метод и аттрибуты родителя.

Инкапсуляция

подробнее

Суть инкапсуляции заключается в том что класс это капсула, содержащая свойства и методы для работы с этими свойствами.
Инкапсуляция - это принцип, который позволяет скрывать внутренние детали работы объекта от внешнего мира и контролировать доступ к его данным.
Получается что объект это чёрный ящик, которы предоставляет некий интерфейс для работы с данными.
В Python сокрытие держится на соглашении, так как все аттрибуты и методы - публичные.

В Python нет настоящей приватности, но есть механизмы для обозначения “внутренних” атрибутов:

  • _одиночное_подчёркивание — сигнал для разработчиков (“не используйте напрямую”).
  • __двойное_подчёркивание — имя искажается, но доступ остаётся.
  • @property — лучший способ контролировать доступ с логикой.

Полиморфизм

подробнее

Полиморфизм - принцип который позволяет одному и тому же блоку кода (методу/функции/классу) работать с разными типами данных.

Полиморфизм делится на:

  • Ad-hoc (мнимый) Заключается в перегрузке аттрибутов функций (когда объявляем такую же функцию, но с другими аттрибутами.)

     print(1 + 2)          # 3 (сложение чисел)
     print("a" + "b")      # "ab" (конкатенация строк)
    

    Приведение типов (когда явно преобразуем один класс к другому) тоже разновидность ad-hoc полиморфизма.

     str(10)  # "10" (преобразование int → str)
    

    Важно: В Python нет классической перегрузки функций как в Java/C++, но операторы и встроенные функции ведут себя по-разному для разных типов — это и есть ad-hoc полиморфизм.

  • Параметрический (истинный)
    Один код работает с любыми типами, если они поддерживают нужный интерфейс.

     # самый простой пример это функция print() которая работает с разными типами данных
     print(123)
     print('aaa')
    

    Полиморфизм подтипов (наследование)

     class Bird:
         def fly(self):
             print("Птица летит")
       
     class Penguin(Bird):
         @override 
         def fly(self):
             print("Пингвин не летает")  # Переопределение
      
     def fly(bird: Bird):
         bird.fly()  # работает с любым подтипом Bird (это и есть полиморфизм).
    

    Полиморфизм за счёт утиной типизации в Python:

     class Duck:
         def quack(self):
             print("Quack!")
       
     class Person:
         def quack(self):
             print("I'm quacking like a duck!")
       
     def make_it_quack(obj):
         obj.quack()
       
     make_it_quack(Duck())   # Quack!
     make_it_quack(Person()) # I'm quacking like a duck!