- Python наследование переопределение init
- Проверка типа объекта
- Обзор наследования классов в Python
- Пример наследования Python
- Создание родительского класса
- Создание дочернего класса
- Добавление функции __init__()
- Различные формы наследования
- Одиночное наследование
- Множественное наследование
- Многоуровневое
- Иерархическое
- Гибридное
Python наследование переопределение init
В прошлой статье класс 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: ") class Employee(Person): def work(self): print(f" 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: ") class Employee(Person): def __init__(self, name, company): super().__init__(name) self.company = company def display_info(self): super().display_info() print(f"Company: ") def work(self): print(f" works") tom = Employee("Tom", "Microsoft") tom.display_info() # Name: Tom # Company: Microsoft
Здесь в классе Employee добавляется новый атрибут — self.company , который хранит компания работника. Соответственно метод __init__() принимает три параметра: второй для установки имени и третий для установки компании. Но если в базом классе определен конструктор с помощью метода __init__, и мы хотим в производном классе изменить логику конструктора, то в конструкторе производного класса мы должны вызвать конструктор базового класса. То есть в конструкторе Employee надо вызвать конструктор класса Person.
Для обращения к базовому классу используется выражение super() . Так, в конструкторе Employee выполняется вызов:
Это выражение будет представлять вызов конструктора класса Person, в который передается имя работника. И это логично. Ведь имя работника устанавливается именно в конструкторе класса Person. В самом конструкторе Employee лишь устанавливаем свойство company.
Кроме того, в классе Employee переопределяется метод display_info() — в него добавляется вывод компании работника. Причем мы могли определить этот метод следующим образом:
def display_info(self): print(f"Name: ") print(f"Company: ")
Но тогда строка вывода имени повторяла бы код из класса Person. Если эта часть кода совпадает с методом из класса Person, то нет смысла повторяться, поэтому опять же с помощью выражения super() обращаемся к реализации метода display_info в классе Person:
def display_info(self): super().display_info() # обращение к методу display_info в классе Person print(f"Company: ")
Затем мы можем вызвать вызвать конструктор Employee для создания объекта этого класса и вызвать метод display_info:
tom = Employee("Tom", "Microsoft") tom.display_info()
Консольный вывод программы:
Name: Tom Company: Microsoft
Проверка типа объекта
При работе с объектами бывает необходимо в зависимости от их типа выполнить те или иные операции. И с помощью встроенной функции isinstance() мы можем проверить тип объекта. Эта функция принимает два параметра:
Первый параметр представляет объект, а второй — тип, на принадлежность к которому выполняется проверка. Если объект представляет указанный тип, то функция возвращает 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" does nothing") # класс работника class Employee(Person): def work(self): print(f" works") # класс студента class Student(Person): def study(self): print(f" 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 определнный тип, и зависимости от результатов проверки обращается к определенному методу объекта.
Обзор наследования классов в Python
Наследование Python позволяет нам определить класс, который наследует все методы и свойства другого класса. Родительский класс — это наследуемый класс, также называемый базовым классом.
Дочерний класс — это класс, который наследуется от другого класса, также называемого производным классом. В данном руководстве рассмотрим обзор наследования классов в Python и примеры.
Пример наследования Python
Наследование — это способность одного класса получать или наследовать свойства какого-либо другого класса. Преимущества наследования:
- Оно хорошо представляет отношения в реальном мире.
- Обеспечивает возможность повторного использования кода. Нам не нужно писать один и тот же код снова и снова. Это также позволяет добавлять дополнительные функции в класс, не изменяя его.
- Оно транзитивно, что означает, что если класс B наследуется от другого класса A, то все подклассы B автоматически наследуются от класса A.
Наследование позволяет нам определить класс, который берет всю функциональность родительского класса и позволяет добавлять больше.
Разобьем приведенный выше код на части.
Создание родительского класса
Создайте класс с именем Person, с именем в качестве свойства и двумя методами getName(), isStudent().
Создание дочернего класса
Если мы хотим создать класс, который наследует функциональность от другого класса, нужно отправить родительский класс в качестве параметра при создании дочернего класса.
Теперь класс Student имеет те же свойства и методы, что и класс Person. Используйте класс Student для создания объекта, а затем выполните методы getName() и isStudent().
Добавление функции __init__()
Мы уже добавили функцию Constructor внутри класса Person.
Это означает, что во время создания объекта мы можем установить свойства класса.
Когда мы добавим функцию __init__() в дочерний класс (в нашем случае это класс Student), дочерний класс больше не будет наследовать родительскую функцию __init__(). Дочерняя функция __init__() переопределяет наследование родительской функции __init__().
Если вы хотите сохранить наследование родительской функции __init__(), добавьте вызов родительской функции __init__(). См. следующий код.
Различные формы наследования
Одиночное наследование
Когда дочерний класс наследуется только от одного родительского класса, это называется одиночным наследованием. Мы видели пример выше.
Множественное наследование
Когда дочерний класс наследуется от нескольких родительских классов, это называется множественным наследованием.
В отличие от Java и C++, Python поддерживает множественное наследование. Мы указываем все родительские классы в виде списка через запятую в скобках.
Многоуровневое
Многоуровневое наследование означает отношения GrandParent -> Parents -> Children.
Иерархическое
Когда более чем один класс является производным от одного базового класса, такое наследование известно как иерархическое наследование, при котором функции, общие для нижнего уровня, включаются в родительский класс.
Проблемы, в которых необходимо поддерживать иерархию, могут быть эффективно решены с использованием этого наследования. Проще говоря, из одной базы создается более одного производного класса.
Гибридное
Гибридное наследование представляет собой комбинацию множественного наследования и многоуровневого наследования. Класс является производным от двух классов, как при множественном наследовании. Однако один из родительских классов не является базовым классом. Это производный класс.
Гибридное наследование сочетает в себе несколько форм наследования. Это смесь более чем одного типа наследования.