Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Subclass в Python
Subclass (подкласс) — это **класс, который наследует свойства и методы от другого класса** (называемого parent class или superclass). Наследование — это один из основных принципов объектно-ориентированного программирования (ООП), позволяющий переиспользовать код и строить иерархии классов.
Основной синтаксис
# Родительский класс (parent class, superclass)
class Animal:
def __init__(self, name: str):
self.name = name
def make_sound(self):
return "Some generic sound"
# Подкласс (subclass, child class)
class Dog(Animal):
pass
# Использование
dog = Dog("Rex")
print(dog.name) # "Rex"
print(dog.make_sound()) # "Some generic sound"
Dog наследует все методы и атрибуты от Animal.
Переопределение методов (Method Overriding)
Подкласс может переопределить методы родительского класса:
class Animal:
def __init__(self, name: str):
self.name = name
def make_sound(self) -> str:
return "Some generic sound"
def describe(self) -> str:
return f"This is {self.name}"
class Dog(Animal):
def make_sound(self) -> str:
return "Woof!"
class Cat(Animal):
def make_sound(self) -> str:
return "Meow!"
class Cow(Animal):
def make_sound(self) -> str:
return "Moo!"
# Использование
dog = Dog("Rex")
cat = Cat("Whiskers")
cow = Cow("Bessie")
print(dog.make_sound()) # "Woof!"
print(cat.make_sound()) # "Meow!"
print(cow.make_sound()) # "Moo!"
# Унаследованный метод работает
print(dog.describe()) # "This is Rex"
Вызов методов родительского класса
Можно вызвать метод родителя с помощью super():
class Animal:
def __init__(self, name: str, age: int = 0):
self.name = name
self.age = age
def info(self) -> str:
return f"{self.name}, age {self.age}"
class Dog(Animal):
def __init__(self, name: str, age: int, breed: str):
super().__init__(name, age) # Вызываем конструктор родителя
self.breed = breed
def info(self) -> str:
parent_info = super().info() # Вызываем метод родителя
return f"{parent_info}, breed {self.breed}"
# Использование
dog = Dog("Rex", 5, "Labrador")
print(dog.info()) # "Rex, age 5, breed Labrador"
Множественное наследование
Подкласс может наследовать от нескольких родительских классов:
class Swimmer:
def swim(self) -> str:
return "Swimming..."
class Flyer:
def fly(self) -> str:
return "Flying..."
class Duck(Swimmer, Flyer):
def quack(self) -> str:
return "Quack!"
# Использование
duck = Duck()
print(duck.swim()) # "Swimming..."
print(duck.fly()) # "Flying..."
print(duck.quack()) # "Quack!"
MRO (Method Resolution Order)
При множественном наследовании Python использует MRO для определения порядка поиска методов:
class A:
def method(self):
return "A"
class B(A):
def method(self):
return "B"
class C(A):
def method(self):
return "C"
class D(B, C):
pass
# Просмотр MRO
print(D.mro()) # [<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>]
d = D()
print(d.method()) # "B" (B идёт раньше C в MRO)
Абстрактные классы
Можно создать абстрактный класс, который нельзя инстанцировать, но только наследовать от него:
from abc import ABC, abstractmethod
class Vehicle(ABC):
@abstractmethod
def start(self):
pass
@abstractmethod
def stop(self):
pass
def describe(self):
return "This is a vehicle"
class Car(Vehicle):
def start(self):
return "Car started"
def stop(self):
return "Car stopped"
# Использование
# vehicle = Vehicle() # TypeError: Can't instantiate abstract class
car = Car()
print(car.start()) # "Car started"
print(car.describe()) # "This is a vehicle"
Проверка наследования
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
# Проверка, является ли dog экземпляром Dog
print(isinstance(dog, Dog)) # True
# Проверка, является ли dog экземпляром Animal (родителя)
print(isinstance(dog, Animal)) # True
# Проверка, является ли Dog подклассом Animal
print(issubclass(Dog, Animal)) # True
# Получение класса объекта
print(type(dog).__name__) # "Dog"
Практический пример: система ролей
from abc import ABC, abstractmethod
from typing import List
class User(ABC):
def __init__(self, username: str, email: str):
self.username = username
self.email = email
@abstractmethod
def get_permissions(self) -> List[str]:
pass
def get_info(self) -> str:
return f"{self.username} ({self.email})"
class Admin(User):
def get_permissions(self) -> List[str]:
return ["read", "write", "delete", "manage_users"]
class Moderator(User):
def get_permissions(self) -> List[str]:
return ["read", "write", "delete"]
class Guest(User):
def get_permissions(self) -> List[str]:
return ["read"]
# Использование
admin = Admin("john_admin", "john@example.com")
mod = Moderator("jane_mod", "jane@example.com")
guest = Guest("bob", "bob@example.com")
users: List[User] = [admin, mod, guest]
for user in users:
print(f"{user.get_info()} - Permissions: {user.get_permissions()}")
# john_admin (john@example.com) - Permissions: ['read', 'write', 'delete', 'manage_users']
# jane_mod (jane@example.com) - Permissions: ['read', 'write', 'delete']
# bob (bob@example.com) - Permissions: ['read']
Преимущества наследования
- Переиспользование кода — не нужно повторять одинаковый код
- Организация — логическая иерархия классов
- Полиморфизм — разные подклассы могут переопределять методы
- Расширяемость — легко добавлять новые подклассы
- Поддержка — изменения в родителе автоматически влияют на детей
Проблемы наследования
- Tight coupling — подкласс тесно связан с родителем
- Хрупкий базовый класс — изменения в родителе могут сломать детей
- Сложность — иерархии могут стать запутанными
- Композиция часто лучше — использовать объекты вместо наследования
Composition vs Inheritance
# Плохо: глубокая иерархия
class Engine:
pass
class Car(Engine):
pass
class SportsCar(Car):
pass
# Хорошо: композиция
class Engine:
def start(self):
return "Engine started"
class Car:
def __init__(self, engine: Engine):
self.engine = engine
def start(self):
return self.engine.start()
Subclass и наследование — это фундаментальные концепции ООП, но их нужно использовать разумно, предпочитая композицию когда это возможно.