Инкапсуляция и полиморфизм - это мощные инструменты объектно-ориентированного программирования, которые помогают создавать гибкие и поддерживаемые системы, особенно при работе с изменяемыми объектами и интерфейсами. Вот как их можно использовать для этой цели:
Инкапсуляция заключается в сокрытии внутреннего состояния объекта и предоставлении контролируемого доступа к нему через методы. Это позволяет:
В Python инкапсуляция достигается соглашениями об именовании (например, префикс _ или __ для обозначения "защищенных" или "приватных" атрибутов) и использованием свойств (@property, @setter) для контролируемого доступа к атрибутам.
Пример:
class TemperatureSensor:
    def __init__(self, temperature):
        self._temperature = temperature  # _temperature is considered "protected"
    @property
    def temperature(self):
        return self._temperature
    @temperature.setter
    def temperature(self, new_temperature):
        if new_temperature < -273.15:  # Absolute zero check
            raise ValueError("Temperature cannot be below absolute zero")
        self._temperature = new_temperature
    В этом примере, атрибут _temperature считается "защищенным".  Доступ и изменение температуры контролируются через свойства temperature, которые выполняют проверку входных данных.
Полиморфизм позволяет объектам разных классов реагировать на один и тот же метод по-разному. Это позволяет:
В Python полиморфизм часто реализуется через:
abc module в Python.Пример:
from abc import ABC, abstractmethod
class Displayable(ABC):
    @abstractmethod
    def display(self):
        pass
class TextDisplay(Displayable):
    def __init__(self, text):
        self.text = text
    def display(self):
        print(f"Text: {self.text}")
class ImageDisplay(Displayable):
    def __init__(self, image_path):
        self.image_path = image_path
    def display(self):
        print(f"Displaying image from: {self.image_path} (Implementation not shown)")
def display_content(content: Displayable):
    content.display()
text_content = TextDisplay("Hello, world!")
image_content = ImageDisplay("path/to/image.jpg")
display_content(text_content)
display_content(image_content)
    В этом примере, Displayable является абстрактным базовым классом, определяющим интерфейс display().  TextDisplay и ImageDisplay реализуют этот интерфейс по-разному. Функция display_content принимает любой объект, реализующий Displayable, демонстрируя полиморфизм.
Предположим, у вас есть система для управления различными типами уведомлений (email, SMS, push-уведомления). Инкапсуляция может использоваться для сокрытия деталей реализации каждого типа уведомления, а полиморфизм - для того, чтобы можно было отправлять уведомления разных типов через общий интерфейс.
В этом случае:
EmailNotification, SMSNotification) инкапсулировать детали отправки уведомлений (например, использование определенных библиотек для работы с email или SMS API).send() для отправки уведомлений любого типа, не зная конкретной реализации отправки.Такой подход делает систему более гибкой, легко расширяемой (можно добавить новые типы уведомлений, просто реализовав интерфейс) и устойчивой к изменениям (изменения в реализации одного типа уведомлений не влияют на другие).