Пример 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
- Создайте папку
python-fundamentals-practice/lesson-70/. - Создайте файл
inheritance.pyи скопируйте в него любой пример. - Откройте терминал в VS Code (Ctrl + `).
- Активируйте виртуальное окружение:
venv\Scripts\activate(Windows) илиsource venv/bin/activate(Mac/Linux). - Запустите:
python inheritance.py