← Назад к вопросам

Как реализуется абстрактный класс в Python?

1.7 Middle🔥 211 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как реализуется абстрактный класс в Python?

Абстрактный класс — это класс, который нельзя инстанцировать напрямую. Он служит шаблоном для подклассов. В Python для этого используется модуль abc (Abstract Base Classes).

Способ 1: Модуль abc (РЕКОМЕНДУЕТСЯ)

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def make_sound(self):
        """Подклассы должны реализовать этот метод"""
        pass
    
    @abstractmethod
    def move(self):
        pass
    
    def describe(self):
        """Обычный метод — может иметь реализацию"""
        return f"I am an {self.__class__.__name__}"

# Попытка создать экземпляр абстрактного класса
try:
    animal = Animal()  # TypeError: Can't instantiate abstract class Animal
except TypeError as e:
    print(e)

# Правильно: создаём подкласс с реализацией
class Dog(Animal):
    def make_sound(self):
        return "Woof!"
    
    def move(self):
        return "Running on four legs"

dog = Dog()  # OK
print(dog.make_sound())    # Woof!
print(dog.describe())      # I am a Dog

Способ 2: Абстрактные свойства (@abstractproperty)

from abc import ABC, abstractmethod

class Vehicle(ABC):
    @property
    @abstractmethod
    def speed(self):
        """Подкласс должен реализовать это свойство"""
        pass
    
    @abstractmethod
    def accelerate(self):
        pass

class Car(Vehicle):
    def __init__(self):
        self._speed = 0
    
    @property
    def speed(self):
        return self._speed
    
    def accelerate(self):
        self._speed += 10
        return f"Speed: {self._speed}"

car = Car()
print(car.speed)           # 0
print(car.accelerate())    # Speed: 10

Способ 3: Абстрактные методы класса

from abc import ABC, abstractmethod

class Factory(ABC):
    @classmethod
    @abstractmethod
    def create_product(cls):
        pass

class ConcreteFactory(Factory):
    @classmethod
    def create_product(cls):
        return "Product"

product = ConcreteFactory.create_product()  # OK
print(product)  # Product

Способ 4: Абстрактные статические методы

from abc import ABC, abstractmethod

class Utils(ABC):
    @staticmethod
    @abstractmethod
    def validate(data):
        pass

class StringUtils(Utils):
    @staticmethod
    def validate(data):
        return isinstance(data, str)

print(StringUtils.validate("hello"))  # True

Полный пример: Система платежей

from abc import ABC, abstractmethod
from typing import Optional

class PaymentProcessor(ABC):
    """Абстрактный класс для обработки платежей"""
    
    @property
    @abstractmethod
    def provider_name(self) -> str:
        """Имя платёжного провайдера"""
        pass
    
    @abstractmethod
    def process_payment(self, amount: float) -> bool:
        """Обработать платёж"""
        pass
    
    @abstractmethod
    def refund(self, transaction_id: str) -> bool:
        """Вернуть платёж"""
        pass
    
    def validate_amount(self, amount: float) -> bool:
        """Обычный метод (не абстрактный)"""
        return amount > 0

# Реализация для Stripe
class StripeProcessor(PaymentProcessor):
    @property
    def provider_name(self) -> str:
        return "Stripe"
    
    def process_payment(self, amount: float) -> bool:
        if not self.validate_amount(amount):
            return False
        print(f"Processing ${amount} with Stripe")
        return True
    
    def refund(self, transaction_id: str) -> bool:
        print(f"Refunding transaction {transaction_id} from Stripe")
        return True

# Реализация для PayPal
class PayPalProcessor(PaymentProcessor):
    @property
    def provider_name(self) -> str:
        return "PayPal"
    
    def process_payment(self, amount: float) -> bool:
        if not self.validate_amount(amount):
            return False
        print(f"Processing ${amount} with PayPal")
        return True
    
    def refund(self, transaction_id: str) -> bool:
        print(f"Refunding transaction {transaction_id} from PayPal")
        return True

# Использование
processors = [
    StripeProcessor(),
    PayPalProcessor()
]

for processor in processors:
    print(f"Provider: {processor.provider_name}")
    processor.process_payment(99.99)
    processor.refund("tx_12345")
    print()

Проверка абстрактности

from abc import ABC, abstractmethod

class Base(ABC):
    @abstractmethod
    def method(self):
        pass

class Incomplete(Base):
    pass  # Не реализовали method()

try:
    obj = Incomplete()  # TypeError!
except TypeError as e:
    print(f"Error: {e}")
    # Error: Can't instantiate abstract class Incomplete with abstract methods method

class Complete(Base):
    def method(self):
        return "Implemented"

obj = Complete()  # OK!
print(obj.method())  # Implemented

Интерфейсы из typing (Python 3.8+)

from typing import Protocol

class Drawable(Protocol):
    """Структурная типизация вместо наследования"""
    def draw(self) -> str:
        ...

class Circle:
    def draw(self) -> str:
        return "Drawing a circle"

class Square:
    def draw(self) -> str:
        return "Drawing a square"

def render(drawable: Drawable) -> str:
    return drawable.draw()

circle = Circle()
square = Square()

print(render(circle))   # Drawing a circle
print(render(square))   # Drawing a square
# Circle и Square не наследуют Drawable, но соответствуют Protocol!

Абстрактные классы vs Интерфейсы (ABC vs Protocol)

# ABC (явное наследование требуется)
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):  # ДОЛЖНА наследовать
    def area(self):
        return 3.14 * r**2

# Protocol (наследование не требуется, структурная типизация)
from typing import Protocol

class Shapeable(Protocol):
    def area(self) -> float:
        ...

class Circle:  # НЕ наследует, но соответствует Protocol
    def area(self) -> float:
        return 3.14 * r**2

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

"Абстрактный класс в Python создаётся через модуль abc:

from abc import ABC, abstractmethod

class MyAbstract(ABC):
    @abstractmethod
    def my_method(self):
        pass

Можно выделить:

  • Не можно инстанцировать абстрактный класс напрямую
  • Подклассы ДОЛЖНЫ реализовать все @abstractmethod методы
  • Обычные методы могут иметь реализацию
  • Можно использовать @property, @classmethod, @staticmethod с @abstractmethod

Это полезно для создания интерфейсов и шаблонов проектирования. Также есть Protocol для структурной типизации (более гибко)."

Это покажет твоё понимание объектно-ориентированного программирования.