← Назад к вопросам
Как реализуется абстрактный класс в 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 для структурной типизации (более гибко)."
Это покажет твоё понимание объектно-ориентированного программирования.