5.1 - Абстрактные классы
5.2 - Протокол

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

Абстрактные классы в Python – это особый тип классов, предназначенный для создания общей структуры для всех классов-наследников. Они используются для того, чтобы заставить классы, наследующие абстрактный класс, реализовывать определённые методы. Если класс содержит хотя бы один абстрактный метод, то он становится абстрактным.

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

Пример абстрактного класса в реальной жизни:

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


Что такое абстрактные классы?

Абстрактный класс – это класс, который определяет один или несколько абстрактных методов, которые не имеют реализации в самом абстрактном классе, но должны быть реализованы в классах-наследниках. Абстрактные методы – это методы, которые объявлены, но не реализованы.


Основные характеристики абстрактных классов:

  1. Абстрактный класс нельзя инстанцировать.
  2. Наличие хотя бы одного абстрактного метода делает класс абстрактным.
  3. Классы-наследники должны реализовать все абстрактные методы.
  4. Абстрактный класс может содержать как абстрактные, так и обычные методы.


Как создавать абстрактные классы?

Для создания абстрактных классов в Python используется модуль abc (Abstract Base Classes). Класс, который должен стать абстрактным, наследуется от ABC, а абстрактные методы обозначаются декоратором @abstractmethod.

Пример создания абстрактного класса:

from abc import ABC, abstractmethod

# Абстрактный класс Transport
class Transport(ABC):

    @abstractmethod
    def move(self):
        """Метод для передвижения транспорта."""
        pass

    @abstractmethod
    def fuel(self):
        """Метод для заправки транспорта."""
        pass

В этом примере:

  • Transport – это абстрактный класс, который содержит два абстрактных метода: move() и fuel().
  • Эти методы должны быть реализованы в классе-наследнике, иначе возникнет ошибка при попытке инстанцирования объекта.


Как использовать абстрактные классы?

Абстрактные классы используются для создания более конкретных классов. Чтобы использовать абстрактный класс, создайте новый класс, который наследуется от абстрактного и реализует все абстрактные методы.

Пример использования:

# Наследуемся от абстрактного класса Transport
class Car(Transport):
    def move(self):
        print("Автомобиль едет по дороге.")

    def fuel(self):
        print("Заправка автомобиля бензином.")

class Airplane(Transport):
    def move(self):
        print("Самолет летит по воздуху.")

    def fuel(self):
        print("Заправка самолета керосином.")

Теперь мы можем создавать объекты классов Car и Airplane, потому что они реализовали все абстрактные методы из класса Transport.

car = Car()
car.move()  # Выведет: Автомобиль едет по дороге.
car.fuel()  # Выведет: Заправка автомобиля бензином.

airplane = Airplane()
airplane.move()  # Выведет: Самолет летит по воздуху.
airplane.fuel()  # Выведет: Заправка самолета керосином.

Однако, если мы попробуем создать объект класса Transport, это вызовет ошибку, так как Transport – абстрактный класс:

# transport = Transport()  # Ошибка: Невозможно инстанцировать абстрактный класс


Примеры и детальные пояснения

Пример 1: Общий интерфейс для животных

Допустим, у нас есть несколько классов, представляющих разных животных, и мы хотим убедиться, что каждое животное может издавать звук.

from abc import ABC, abstractmethod

# Абстрактный класс Animal
class Animal(ABC):
    
    @abstractmethod
    def make_sound(self):
        pass

# Реализация для собаки
class Dog(Animal):
    def make_sound(self):
        print("Гав-гав!")

# Реализация для кошки
class Cat(Animal):
    def make_sound(self):
        print("Мяу-мяу!")

В этом примере абстрактный класс Animal имеет абстрактный метод make_sound(), который должен быть реализован в каждом классе-наследнике. Классы Dog и Cat реализуют этот метод.

dog = Dog()
dog.make_sound()  # Выведет: Гав-гав!

cat = Cat()
cat.make_sound()  # Выведет: Мяу-мяу!


Пример 2: Платёжные системы

Представим, что вы разрабатываете систему для обработки различных платёжных систем. Каждая платёжная система должна поддерживать метод pay() для совершения платежа и метод refund() для возврата.

from abc import ABC, abstractmethod

# Абстрактный класс PaymentSystem
class PaymentSystem(ABC):

    @abstractmethod
    def pay(self, amount):
        """Метод для совершения платежа."""
        pass

    @abstractmethod
    def refund(self, amount):
        """Метод для возврата средств."""
        pass

# Реализация платёжной системы для кредитной карты
class CreditCardPayment(PaymentSystem):
    def pay(self, amount):
        print(f"Оплата {amount} с помощью кредитной карты.")

    def refund(self, amount):
        print(f"Возврат {amount} на кредитную карту.")

# Реализация платёжной системы для PayPal
class PayPalPayment(PaymentSystem):
    def pay(self, amount):
        print(f"Оплата {amount} через PayPal.")

    def refund(self, amount):
        print(f"Возврат {amount} через PayPal.")

Теперь вы можете использовать классы CreditCardPayment и PayPalPayment для выполнения платежей:

python

Копировать код

credit_card_payment = CreditCardPayment()
credit_card_payment.pay(100)  # Выведет: Оплата 100 с помощью кредитной карты.
credit_card_payment.refund(50)  # Выведет: Возврат 50 на кредитную карту.

paypal_payment = PayPalPayment()
paypal_payment.pay(200)  # Выведет: Оплата 200 через PayPal.
paypal_payment.refund(100)  # Выведет: Возврат 100 через PayPal.


Пример 3: Геометрические фигуры

Теперь рассмотрим пример, где мы создаём абстрактный класс для геометрических фигур. У каждой фигуры должен быть метод для расчёта площади.

from abc import ABC, abstractmethod

# Абстрактный класс для фигур
class Shape(ABC):

    @abstractmethod
    def area(self):
        pass

# Реализация для прямоугольника
class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

# Реализация для круга
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * (self.radius ** 2)

Теперь можно создать объект прямоугольника или круга и посчитать их площади:

rect = Rectangle(10, 5)
print(rect.area())  # Выведет: 50

circle = Circle(3)
print(circle.area())  # Выведет: 28.26

Таблица по лекции:

ТемаОписание
Что такое абстрактные классы?Абстрактный класс – это класс, содержащий один или несколько абстрактных методов. Эти методы должны быть реализованы в классах-наследниках. Абстрактный класс нельзя инстанцировать.
Основные характеристики- Нельзя создать объект абстрактного класса. 
- Наличие хотя бы одного абстрактного метода делает класс абстрактным. 
- Классы-наследники обязаны реализовать все абстрактные методы. 
- Абстрактные классы могут содержать как абстрактные, так и обычные методы.
Как создать абстрактный класс?Для создания абстрактного класса необходимо унаследоваться от класса ABC и использовать декоратор @abstractmethod для определения абстрактных методов.
Пример 1: Транспортные средстваСоздаем абстрактный класс Transport, а затем реализуем его в классах-наследниках Car и Airplane, реализуя методы move() и fuel().
Пример 2: ЖивотныеАбстрактный класс Animal с методом make_sound(). Классы Dog и Cat реализуют этот метод по-своему.
Пример 3: Платежные системыАбстрактный класс PaymentSystem с методами pay() и refund(). Реализуем эти методы в классах CreditCardPayment и PayPalPayment.
Пример 4: Геометрические фигурыАбстрактный класс Shape с методом area(). Классы Rectangle и Circle реализуют этот метод по-разному для расчета площади прямоугольника и круга соответственно.
Где используются абстрактные классы?- Проектирование интерфейсов и API 
- Полиморфизм: единый набор методов для всех наследников 
- Шаблоны для фреймворков и библиотек

Где реально используются абстрактные классы?

  1. Проектирование интерфейсов и API: Абстрактные классы широко используются для проектирования интерфейсов или API, когда нужно задать общую структуру и убедиться, что все классы-наследники реализуют определённые методы.
  2. Работа с полиморфизмом: Абстрактные классы обеспечивают, чтобы все классы-наследники имели одинаковый набор методов, что упрощает использование полиморфизма.
  3. Создание шаблонов для фреймворков: Многие фреймворки используют абстрактные классы для создания шаблонов, которые программисты должны использовать и заполнять своей реализацией.

Перейти к следующему шагу

Комментарии