В прошлой статье класс Employee полностью перенимал функционал класса Person:
class Person: def __init__(self, name): self.__name = name # имя человека @property def name(self): return self.__name def display_info(self): print(f"Name: {self.__name} ") class Employee(Person): def work(self): print(f"{self.name} works")
Но что, если мы хотим что-то изменить из этого функционала? Например, добавить работнику через конструктор, новый атрибут, который будет хранить компанию, где он работает или изменить реализацию метода display_info. Python позволяет переопределить функционал базового класса.
Например, изменим классы следующим образом:
class Person: def __init__(self, name): self.__name = name # имя человека @property def name(self): return self.__name def display_info(self): print(f"Name: {self.__name}") class Employee(Person): def __init__(self, name, company): super().__init__(name) self.company = company def display_info(self): super().display_info() print(f"Company: {self.company}") def work(self): print(f"{self.name} works") tom = Employee("Tom", "Microsoft") tom.display_info() # Name: Tom # Company: Microsoft
Здесь в классе Employee добавляется новый атрибут - self.company
, который хранит компания работника. Соответственно метод __init__()
принимает три параметра: второй для установки имени и третий для установки компании. Но если в базом классе определен конструктор с помощью метода __init__, и
мы хотим в производном классе изменить логику конструктора, то в конструкторе производного класса мы должны вызвать конструктор базового класса. То есть в конструкторе Employee надо вызвать конструктор класса Person.
Для обращения к базовому классу используется выражение super(). Так, в конструкторе Employee выполняется вызов:
super().__init__(name)
Это выражение будет представлять вызов конструктора класса Person, в который передается имя работника. И это логично. Ведь имя работника устанавливается именно в конструкторе класса Person. В самом конструкторе Employee лишь устанавливаем свойство company.
Кроме того, в классе Employee переопределяется метод display_info()
- в него добавляется вывод компании работника. Причем мы могли определить этот метод
следующим образом:
def display_info(self): print(f"Name: {self.name}") print(f"Company: {self.company}")
Но тогда строка вывода имени повторяла бы код из класса Person. Если эта часть кода совпадает с методом из класса Person, то нет смысла повторяться, поэтому опять же с помощью выражения super() обращаемся к реализации метода display_info в классе Person:
def display_info(self): super().display_info() # обращение к методу display_info в классе Person print(f"Company: {self.company}")
Затем мы можем вызвать вызвать конструктор Employee для создания объекта этого класса и вызвать метод display_info:
tom = Employee("Tom", "Microsoft") tom.display_info()
Консольный вывод программы:
Name: Tom Company: Microsoft
При работе с объектами бывает необходимо в зависимости от их типа выполнить те или иные операции. И с помощью встроенной функции isinstance() мы можем проверить тип объекта. Эта функция принимает два параметра:
isinstance(object, type)
Первый параметр представляет объект, а второй - тип, на принадлежность к которому выполняется проверка. Если объект представляет указанный тип, то функция возвращает True. Например, возьмем следующую иерархию классов Person-Employee/Student:
class Person: def __init__(self, name): self.__name = name # имя человека @property def name(self): return self.__name def do_nothing(self): print(f"{self.name} does nothing") # класс работника class Employee(Person): def work(self): print(f"{self.name} works") # класс студента class Student(Person): def study(self): print(f"{self.name} studies") def act(person): if isinstance(person, Student): person.study() elif isinstance(person, Employee): person.work() elif isinstance(person, Person): person.do_nothing() tom = Employee("Tom") bob = Student("Bob") sam = Person("Sam") act(tom) # Tom works act(bob) # Bob studies act(sam) # Sam does nothing
Здесь класс Employee определяет метод work(), а класс Student - метод study.
Здесь также определена функция act
, которая проверяет с помощью функции isinstance
, представляет ли параметр person определнный тип, и зависимости
от результатов проверки обращается к определенному методу объекта.