Наследование в 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) # also possible # 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
Пример с новыми методами
Теперь создадим класс 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]) mgr_1.print_emps() print(mgr_1.email) mgr_1.add_emp(dev_2) mgr_1.print_emps() print(mgr_1.fullname()) 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
--> Eugene Kaspersky Sue.Smith@kaspersky --> Eugene Kaspersky --> Test User Sue Smith --> 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]) mgr_1.print_emps() print(mgr_1.email) mgr_1.add_emp(dev_2) mgr_1.print_emps() print(mgr_1.fullname()) 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))
OOP in Python | |
Classes | |
Methods | |
class variables | |
class methods | |
Static Methods | |
Inheritance | |
Special Methods | |
property decorator | |
Python | |
Functions | |
super() |