Python: Погружаясь в классы
Теория: Модификаторы доступа
Наследование — это важная концепция объектно-ориентированного программирования, которая позволяет одним классам наследовать функциональность, свойства и методы других классов. Но нужно понимать, как отдельные методы и свойства становятся доступными в процессе наследования.
В этом случае помогают публичные, приватные и защищенные методы и свойства, которые позволяют управлять уровнем доступа к определенным аспектам класса. В этом уроке разберемся с этим в деталях.
Модификаторы доступа в Python
Python не предоставляет никакой системы строгой инкапсуляции, которая присуща некоторым языкам программирования. Из-за этого вы можете получить доступ к любому атрибуту или методу класса из внешнего кода. Однако существует общепринятое соглашение между разработчиками, что атрибуты и методы, предназначенные для внутреннего использования, должны начинаться с подчеркивания (например, _visible). Это подчеркивание служит индикатором для других разработчиков, что этот атрибут или метод не должен изменяться напрямую извне. Но всегда следует помнить, что Python не предоставляет никаких средств для принудительного соблюдения этого соглашения, и атрибуты с подчеркиванием по-прежнему доступны извне.
Публичные атрибуты и методы
Свойства видимости объектов оказывают влияние не только на внешнее поведение объектов, но и на взаимодействие между классами, которые наследуют их. Публичные свойства и методы доступны всем наследникам и создаются простым определением их в теле класса без каких-либо особых префиксов. К ним можно обращаться как внутри объекта, так и снаружи.
В следующем примере мы создаем два класса: HTMLElement и DivElement. DivElement является потомком HTMLElement и наследует его атрибуты и методы:
Здесь DivElement имеет доступ как к атрибуту visible, так и к методу is_visible(), унаследованным от HTMLElement.
Количество классов в цепочке наследования не влияет на это поведение. Любой подкласс DivElement тоже получит доступ к публичным частям HTMLElement:
В данном примере мы видим, что DivElementWithEmptyBody наследуется от DivElement и имеет доступ к атрибутам и методам классов DivElement и HTMLElement.
Наследование не влияет на поведение свойств внутри объектов. Значение visible в каждом конкретном объекте связано только с этим объектом:
Хотя публичные атрибуты и методы имеют свои преимущества, например, доступность из любого места кода, они также могут представлять определенные риски. К ним можно обращаться и изменять их напрямую из любого класса, что может привести к неожиданным последствиям. Поэтому в некоторых случаях предпочтительно использовать приватные атрибуты и методы.
Приватные атрибуты и методы
Свойства и методы с приватным модификатором доступа доступны только внутри того класса, где они были определены. Приватные свойства и методы в Python создаются путем добавления двойного подчеркивания (__) перед именем атрибута или метода.
Наследники не могут получить доступ к приватным свойствам и методам. Подразумевается, что приватные сущности — это нечто персональное для класса — его внутренняя реализация, которую нельзя выставлять наружу. Но это не отменяет возможности взаимодействовать с приватными данными через публичный интерфейс:
Здесь прямой доступ к приватному атрибуту __visible вызывает ошибку. При этом мы все еще можем получить доступ к значению этого атрибута через публичный метод is_visible().
Приватный модификатор доступа представляет собой мощный механизм инкапсуляции, который позволяет скрыть детали реализации класса. Это помогает сохранить целостность данных и избежать нежелательных изменений во внутреннем состоянии объекта.
Но что делать, когда нам нужен компромисс между полной открытостью публичных и строгим ограничением приватных атрибутов и методов? Для данной ситуации существуют защищенные атрибуты и методы.
Защищенные атрибуты и методы
Защищенные атрибуты и методы имеют необычное поведение. Это смесь между публичными и приватными.
Они создаются путем добавления одного подчеркивания (_) перед именем атрибута или метода. Также они используются, когда разработчик хочет запретить доступ снаружи объекта, но дать возможность работать с ними внутри объекта класса-наследника или суперкласса.
Посмотрим, как это работает на практике:
Защищенные атрибуты и методы в Python рассматриваются как внутренние части класса, и, хотя они могут быть доступны извне, это считается плохой практикой. Вместо этого следует придерживаться соглашения и не обращаться к ним напрямую.
Name Mangling
В Python, в отличие от некоторых других языков, можно определять в наследниках методы совпадающие именами с приватными методами родителя. Но как тогда избежать перезаписи родительского метода? Для этого в языке незаметно от программиста используется механизм name mangling. К названию приватного метода добавляется также название его класса. Так, приватные методы в родителях на самом деле начинаются с имени родительского класса, а в наследниках - с имени наследника.
Таким образом мы можем "защитить" родительские методы от изменения в наследниках. Но стоит помнить, что в Python по-настоящему все доступно для разработчика. И добраться до оригинального родительского метода всегда можно обойдя name mangling как _ИмяКласса__имя_метода.
Разумеется, несмотря на то, что мы знаем как добраться до "оригинала" обходить name mangling крайне опасно, ведь если родительский метод был приватным, значит были причины сделать его таким и неизменяемым в наследниках.
Выбор способа
Мы только начали знакомиться с наследованием, но уже сейчас видно, что всё не просто. Одну и ту же задачу можно сделать множеством способов. Какой предпочесть?
Универсальная стратегия, которой стоит придерживаться в большинстве случаев, – всегда работать через абстракцию, пока она не мешает. Это значит, что все свойства, которые не предназначены для прямого доступа, делаются с префиксом подчеркивания (соглашение о защищенности), а наружу выставляется публичный интерфейс (методы).
Выводы
Чтобы правильно использовать наследование в объектно-ориентированном программировании, необходимо понимать публичные, приватные и защищенные атрибуты и методы. Эти модификаторы доступа позволяют управлять уровнем доступа к функциональности и данным класса, обеспечивая инкапсуляцию и полиморфизм. В итоге это способствует созданию гибкого и надежного кода.
Рекомендуемые программы
Завершено
0 / 14

