Абстракция, инкапсуляция и полиморфизм — это ключевые принципы объектно-ориентированного программирования (ООП). В Python их можно реализовать следующим образом:
Абстракция:
Абстракция заключается в представлении пользователю только необходимой информации об объекте, скрывая детали реализации. В Python абстракция достигается несколькими способами:
Пример абстрактного класса:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius * self.radius
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
# shape = Shape() # Ошибка: Нельзя создать экземпляр абстрактного класса
circle = Circle(5)
square = Square(4)
print(f"Площадь круга: {circle.area()}")
print(f"Площадь квадрата: {square.area()}")
В этом примере `Shape` - абстрактный класс с абстрактным методом `area`. Классы `Circle` и `Square` наследуются от `Shape` и реализуют метод `area`, предоставляя конкретную реализацию для вычисления площади каждой фигуры.
Инкапсуляция:
Инкапсуляция заключается в сокрытии внутреннего состояния объекта и предоставлении доступа к нему только через методы. Это позволяет защитить данные от некорректного использования и упростить изменение реализации класса без влияния на остальной код.
Пример инкапсуляции:
class BankAccount:
def __init__(self, balance):
self.__balance = balance # Приватный атрибут
def deposit(self, amount):
if amount > 0:
self.__balance += amount
else:
print("Сумма депозита должна быть положительной")
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
else:
print("Недостаточно средств или некорректная сумма для снятия")
def get_balance(self):
return self.__balance # Getter
account = BankAccount(1000)
account.deposit(500)
account.withdraw(200)
print(f"Баланс: {account.get_balance()}")
#print(account.__balance) # Ошибка: AttributeError: 'BankAccount' object has no attribute '__balance'
print(account._BankAccount__balance) # Можно, но не рекомендуется. Наглядная иллюстрация name mangling
В этом примере `__balance` — приватный атрибут. Доступ к нему извне класса осуществляется только через методы `deposit`, `withdraw` и `get_balance`, которые обеспечивают контроль над операциями с балансом.
Полиморфизм:
Полиморфизм означает "много форм". В контексте ООП, это означает, что объекты разных классов могут быть использованы единообразно, если они реализуют один и тот же интерфейс (набор методов).
Пример полиморфизма:
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow!"
def animal_sound(animal):
print(animal.speak())
dog = Dog()
cat = Cat()
animal_sound(dog)
animal_sound(cat)
Функция `animal_sound` принимает объект типа `animal` (любого класса) и вызывает метод `speak`. Неважно, является ли объект собакой или кошкой, главное, чтобы у него был метод `speak`. Это и есть полиморфизм.
Взаимосвязь:
Эти три принципа тесно связаны между собой. Абстракция определяет общий интерфейс, инкапсуляция скрывает детали реализации, а полиморфизм позволяет использовать объекты разных классов через общий интерфейс.