Наследование в Python

Содержание
Введение
Пример
Пример 2
Пример 3
Похожие статьи

Введение

Это продолжение статьи «Классы» из раздела «ООП в Python» .

Для лучшего понимания этого материала пригодятся знания из следующих статей: Методы , Класс методы , Статические методы , super() , Декораторы , isinstance()

Наследование (англ. inheritance) — концепция объектно-ориентированного программирования, согласно которой абстрактный тип данных может наследовать данные и функциональность некоторого существующего типа, способствуя повторному использованию компонентов программного обеспечения.

Чтобы один класс наследовал от другого нужно при объявлении класса передать родительский класс как аргумент.

class A: def funcA(self): print("A") class B(A): def funcB(self): print("B") b = B() A.funcA = B.funcB b.funcA()

B

Пример

Создадим класс Employee и производный от него класс Developer.

Developer - наследник Employee. Для начала у Developer не будет функционала - просто убедимся, что у объекта производного класса есть те же атрибуты, что и у родитльского. Также проверим что можно применять методы из родительского класса. В конце изучим класс с помощью help.

class Employee: num_of_emps = 0 raise_amt = 1.04 def __init__(self, first, last, pay): self.first = first self.last = last self.pay = pay self.email = first + '.' + last + '@kaspersky.com' Employee.num_of_emps += 1 def fullname(self): return f'{self.first} {self.last}' def apply_raise(self): self.pay = int(self.pay * self.raise_amt) class Developer(Employee): pass dev_1 = Developer('Eugene', 'Kaspersky', 50000) dev_2 = Developer('Test', 'User', 60000) print(dev_1.email) print(dev_2.email) print(dev_1.pay) dev_1.apply_raise() print(dev_1.pay) print(help(Developer))

python inheritance_example.py

Eugene.Kaspersky@kaspersky.com Test.User@kaspersky.com 50000 52000 Help on class Developer in module __main__: class Developer(Employee) | Developer(first, last, pay) | | Method resolution order: | Developer | Employee | builtins.object | | Class methods defined here: | | from_string(emp_str) from builtins.type | | set_raise_amt(amount) from builtins.type | | ---------------------------------------------------------------------- | Static methods defined here: | | is_workday(day) | | ---------------------------------------------------------------------- | Methods inherited from Employee: | | __init__(self, first, last, pay) | Initialize self. See help(type(self)) for accurate signature. | | apply_raise(self) | | fullname(self) | | ---------------------------------------------------------------------- | Data descriptors inherited from Employee: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) | | ---------------------------------------------------------------------- | Data and other attributes inherited from Employee: | | num_of_emps = 2 | | raise_amt = 1.04 (END)

Пример с новыми атрибутами

Добавим классу Developer новый атрибут - язык программирования. Также создадим для этого класса метод __init__()

class Employee: num_of_emps = 0 raise_amt = 1.04 def __init__(self, first, last, pay): self.first = first self.last = last self.pay = pay self.email = first + '.' + last + '@kaspersky.com' Employee.num_of_emps += 1 def fullname(self): return f'{self.first} {self.last}' def apply_raise(self): self.pay = int(self.pay * self.raise_amt) class Developer(Employee): raise_amt = 1.10 def __init__(self, first, last, pay, prog_lang): super().__init__(first, last, pay) # Также можно было написать: # super(Developer, self).__init__(first, last, pay) # или # Employee.__init__(self, first, last, pay) self.prog_lang = prog_lang emp_1 = Employee('Andrei', 'Olegovich', 40000) dev_1 = Developer('Eugene', 'Kaspersky', 50000, 'Python') dev_2 = Developer('Test', 'User', 60000, 'Java') print(f"emp_1 raise_amt: {emp_1.raise_amt}") # 1.04 print(f"dev_1 raise_amt: {dev_1.raise_amt}") # 1.1 print(f"dev_1 Email: {dev_1.email}") print(dev_1.prog_lang) # Python

python inheritance_example.py

emp_1 raise_amt: 1.04 dev_1 raise_amt: 1.1 dev_1 Email: Eugene.Kaspersky@kaspersky.com Python

При созданиее нового девелопера, с помощью super() был переиспользован метод __init__() из класса Employee. Это позволило девелоперу иметь email, хотя в коде объявления про email нет упоминания.

Пример с новыми методами

Теперь создадим класс Manager, у которого будут новые атрибуты и новые методы для работы с ними.

class Manager(Employee): def __init__(self, first, last, pay, employees=None): super().__init__(first, last, pay) if employees is None: self.employees = [] else: self.employees = employees def add_emp(self, emp): if emp not in self.employees: self.employees.append(emp) def remove_emp(self, emp): if emp in self.employees: self.employees.remove(emp) def print_emps(self): for emp in self.employees: print('-->', emp.fullname()) mgr_1 = Manager('Sue', 'Smith', 90000, [dev_1]) print(mgr_1.fullname()) print(mgr_1.email) mgr_1.print_emps() print("add dev_2") mgr_1.add_emp(dev_2) mgr_1.print_emps() print("remove dev_1") mgr_1.remove_emp(dev_1) mgr_1.print_emps() print(isinstance(mgr_1, Manager)) print(isinstance(mgr_1, Employee)) print(isinstance(mgr_1, Developer)) print(issubclass(Manager, Employee)) print(issubclass(Developer, Employee)) print(issubclass(Manager, Developer))

python inheritance_example.py

Sue Smith Sue.Smith@kaspersky --> Eugene Kaspersky add dev_2 --> Eugene Kaspersky --> Test User remove dev_1 --> Test User True True False True True False

Полный код

class Employee: num_of_emps = 0 raise_amt = 1.04 def __init__(self, first, last, pay): self.first = first self.last = last self.pay = pay self.email = first + '.' + last + '@kaspersky.com' Employee.num_of_emps += 1 def fullname(self): return f'{self.first} {self.last}' def apply_raise(self): self.pay = int(self.pay * self.raise_amt) @classmethod def set_raise_amt(cls, amount): cls.raise_amt = amount @classmethod def from_string(cls, emp_str): first, last, pay = emp_str.split('-') return cls(first, last, pay) @staticmethod def is_workday(day): if day.weekday() == 5 or day.weekday() == 6: return False return True class Developer(Employee): raise_amt = 1.10 def __init__(self, first, last, pay, prog_lang): super().__init__(first, last, pay) # also possible # Employee.__init__(self, first, last, pay) self.prog_lang = prog_lang class Manager(Employee): def __init__(self, first, last, pay, employees=None): super().__init__(first, last, pay) if employees is None: self.employees = [] else: self.employees = employees def add_emp(self, emp): if emp not in self.employees: self.employees.append(emp) def remove_emp(self, emp): if emp in self.employees: self.employees.remove(emp) def print_emps(self): for emp in self.employees: print('-->', emp.fullname()) emp_1 = Employee('Andrei', 'Olegovich', 40000) dev_1 = Developer('Eugene', 'Kaspersky', 50000, 'Python') dev_2 = Developer('Test', 'User', 60000, 'Java') print(f"emp_1 raise_amt: {emp_1.raise_amt}") # 1.04 print(f"dev_1 raise_amt: {dev_1.raise_amt}") # 1.1 print(f"dev_1 Email: {dev_1.email}") print(dev_1.prog_lang) # Python mgr_1 = Manager('Sue', 'Smith', 90000, [dev_1]) print(mgr_1.fullname()) print(mgr_1.email) mgr_1.print_emps() print("add dev_2") mgr_1.add_emp(dev_2) mgr_1.print_emps() print("remove dev_1") mgr_1.remove_emp(dev_1) mgr_1.print_emps() print(isinstance(mgr_1, Manager)) print(isinstance(mgr_1, Employee)) print(isinstance(mgr_1, Developer)) print(issubclass(Manager, Employee)) print(issubclass(Developer, Employee)) print(issubclass(Manager, Developer))

Похожие статьи
ООП в Python
Классы
Методы
class variables
class methods
Статические методы
Наследование
Специальные методы
dataclass
__slots__
Декоратор property
super()

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: