Объектно-ориентированное программирование (ООП) — это парадигма программирования, организующая код в классы и объекты. Есть четыре ключевых принципа ООП: инкапсуляция, абстракция, наследование и полиморфизм. Более подробную информацию о том, что такое ООП концептуально, можно найти здесь: Что такое объектно-ориентированное программирование (ООП)? В этой статье мы рассмотрим концепции ООП с использованием Python, создавая классы/объекты для чертежей и зданий.

Классы и объекты в Python

Python поддерживает ООП, и класс можно создать с помощью ключевого слова `class` (подробнее см. Документацию по Python).

В приведенном выше коде создается класс с именем BluePrint. Чтобы инициализировать или создать объект с помощью класса, необходимо указать атрибуты «floor» и «color» (поэтому они являются входными данными для функции «__init__»). Кроме того, есть два метода: `is_tall_building`, который определяет, является ли здание высоким, и `print_is_tall_building`, который распечатывает результаты.

Из этого класса `BluePrint` мы создаем два объекта: `buildingA` и `buildingB`, инициализируя их соответствующими атрибутами пола и цвета (строки 21–22). Обратите внимание, что `print_is_tall_building` был определен в классе только один раз, но и `buildingA`, и `buildingB` (и любые будущие экземпляры класса) могут использовать эту функцию (строки 25–26). Это также верно для `is_tall_building` и любых других методов, которые мы могли бы определить в классе `BluePrint`.

(Примечание: ключевое слово `self` позволяет получить доступ к атрибутам и методам класса. Именно так Python отличает переменные и функции, определенные для класса, от внешних по отношению к классу).

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

Это относится к тому, что код является автономным. Обратите внимание, что в конструкции нашего класса BluePrint содержится вся необходимая информация (для этого упрощенного примера). При создании объектов из класса в строках 21–22 дополнительные компоненты не понадобились.

Абстракция

Это относится к скрытому коду. В Python мы можем пометить методы, которые являются закрытыми, добавив перед именем метода два символа подчеркивания (__). (Примечание: Python не поддерживает приватные методы, но префикс с двойным подчеркиванием является соглашением, указывающим на то, что метод является приватным; пользователи по-прежнему могут получить доступ к приватному методу через изменение имени).

Единственная модификация выше находится в строках 9 и 19, где имя метода меняется с `is_tall_building` на `__is_tall_building`. Делая это, разработчик класса указывает пользователю, что функция является закрытой. Результатом этого является разделение между логикой и интерфейсом: функция `__is_tall_building` обрабатывает логику определения того, является ли здание высоким, тогда как функция `print_is_tall_building` представляет собой интерфейс для взаимодействия пользователя с информацией.

Еще одно полезное свойство абстракции заключается в том, что разработчик может обновлять реализацию методов внутри класса, не нарушая последующего использования (если ожидаемые входные и выходные данные остаются прежними).

Обратите внимание, что в приведенном выше фрагменте кода `__is_tall_building` была изменена, чтобы удалить ненужную переменную `tall_building_lower_bound`. Однако последующее использование класса по-прежнему работает так же, потому что интерфейс остался прежним. Эта функция позволяет разработчикам постоянно обновлять/улучшать свой код, не нарушая код всех, кто использует их класс.

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

Это относится к созданию новых дочерних классов из родительского класса.

В приведенном выше коде есть новый класс SingleFamilyBluePrint, начиная со строки 17, который наследует свойства и методы класса BluePrint. Использование ключевого слова `super()` позволяет нам получить доступ к родительскому классу. Кроме того, `SingleFamilyBluePrint` имеет свой собственный настраиваемый атрибут, has_garden, который указывает, есть ли сад, и свойства, а именно, что этаж всегда равен 1. Обратите внимание, что, наследуя класс, мы можем ссылаться на функцию `is_tall_building` в строке 28, который был определен в родительском классе. Для более сложных классов это свойство может повысить удобство повторного использования и организацию кода.

Полиморфизм

Это относится к возможности использовать один и тот же интерфейс для разных классов/объектов. Обратите внимание, что в приведенном выше примере `print_is_tall_building` настроен для нового класса, но эффект тот же — он печатает, является ли здание высоким или нет. Это полезно, потому что разные классы могут быть настроены, но интерфейс может быть разработан таким образом, чтобы они были одинаковыми — в этом случае мы можем запрограммировать все нюансы различных типов зданий, сохраняя при этом то, как пользователи взаимодействуют с ними одинаковыми/похожими (что имеет смысл для этого примера из-за общего потока в классах).

Заключение

Python позволяет использовать ООП, создавая классы с ключевым словом class и объекты, используя имена классов. В этой статье мы рассмотрели пример с чертежами и зданиями, демонстрирующий инкапсуляцию, абстракцию, наследование и полиморфизм (подробнее об этих понятиях здесь: Что такое объектно-ориентированное программирование (ООП)?).