💻 Практические примеры

⚡ Минимальный рабочий пример

class Employee:
    def work(self) -> None:
        print("Working...")


class Programmer(Employee):
    pass


p = Programmer()
p.work()  # Working...

Пример 1. Наследование полей и методов

Базовый класс задаёт общие данные и поведение, а наследники получают их бесплатно.

class Employee:
    def __init__(self, name: str) -> None:
        self.name = name

    def work(self) -> None:
        print(f"{self.name} is working...")


class Programmer(Employee):
    pass


class Manager(Employee):
    pass


programmer = Programmer("Alice")
manager = Manager("Bob")

programmer.work()
manager.work()

Что происходит: Programmer и Manager не определяют собственный __init__ и work, поэтому используют версии из Employee.

Пример 2. Переопределение метода

Полиморфизм в действии: один и тот же вызов work() ведёт себя по-разному.

class Employee:
    def __init__(self, name: str) -> None:
        self.name = name

    def work(self) -> None:
        print(f"{self.name} is working...")


class Programmer(Employee):
    def work(self) -> None:
        print(f"{self.name} writing code...")


class Manager(Employee):
    def work(self) -> None:
        print(f"{self.name} managing team...")


staff = [Programmer("Alice"), Manager("Bob"), Programmer("Bill")]

for person in staff:
    person.work()

Пример 3. Попытка перегрузки

В Python последнее определение метода заменяет предыдущее.

class Math:
    def add(self, a: int, b: int) -> int:
        return a + b

    def add(self, a: int, b: int, c: int) -> int:
        return a + b + c


m = Math()
print(m.add(1, 2, 3))  # 6
# print(m.add(1, 2))   # TypeError: add() missing 1 required positional argument

Пример 4. super() в __init__

Дочерний класс добавляет собственные поля, но общие поля инициализирует через родителя.

class Employee:
    def __init__(self, name: str) -> None:
        self.name = name


class Programmer(Employee):
    def __init__(self, name: str, language: str) -> None:
        super().__init__(name)
        self.language = language


class Manager(Employee):
    def __init__(self, name: str, department: str) -> None:
        super().__init__(name)
        self.department = department


p = Programmer("Alice", "Python")
print(p.name, p.language)

m = Manager("Bob", "Development")
print(m.name, m.department)

Пример 5. Многоуровневое наследование

super() проходит по цепочке наследников и вызывает нужный метод.

class Person:
    def __init__(self, name: str) -> None:
        self.name = name
        print(f"Init Person: {self.name}")


class Employee(Person):
    def work(self) -> None:
        print(f"{self.name} is working...")


class Manager(Employee):
    def __init__(self, name: str, department: str) -> None:
        super().__init__(name)
        self.department = department
        print(f"Init Manager: {self.name} manages {self.department}")


m = Manager("Alice", "Development")

Пример 6. super() в обычном методе

Расширяем поведение родителя, а не заменяем его полностью.

class Employee:
    def work(self) -> None:
        print("Employee is doing general tasks.")


class Programmer(Employee):
    def work(self) -> None:
        super().work()
        print("Programmer is writing code.")


class Manager(Employee):
    def work(self) -> None:
        super().work()
        print("Manager is holding a meeting.")


staff = [Programmer(), Manager()]
for person in staff:
    person.work()
    print()

Пример 7. isinstance и issubclass

Проверка типов помогает безопасно вызывать специфичные методы.

class Employee:
    def work(self) -> None:
        print("Выполняет общие задачи")


class Programmer(Employee):
    def write_code(self) -> None:
        print("Пишет код")


class Manager(Employee):
    def work(self) -> None:
        print("Проводит собрание")


staff = [Programmer(), Manager(), Employee()]

for person in staff:
    if isinstance(person, Programmer):
        person.write_code()
    else:
        person.work()

print(issubclass(Programmer, Employee))  # True
print(issubclass(Manager, Programmer))   # False

Пример 8. Наследование от object

Даже пустой класс получает методы от object.

class Book:
    pass


b = Book()
print(b.__str__())
print(b)
print(isinstance(b, object))  # True

Как запустить в VS Code

  1. Создайте папку python-fundamentals-practice/lesson-70/.
  2. Создайте файл inheritance.py и скопируйте в него любой пример.
  3. Откройте терминал в VS Code (Ctrl + `).
  4. Активируйте виртуальное окружение: venv\Scripts\activate (Windows) или source venv/bin/activate (Mac/Linux).
  5. Запустите: python inheritance.py
Проверить по документации: примеры дополнены аннотациями типов, которых не было в исходном материале. Подробнее о типах см. typing и PEP 484.