Наследование в Python
Наследование позволяет объявить класс, который дублирует функциональность уже существующего класса. С помощью этой концепции вы сможете расширить возможности своего класса.
Наследование — одна из концепций объектно-ориентированного программирования (ООП).
Как было сказано выше, наследование позволяет объявить класс, который либо не отличается от существующего, либо содержит минимальные изменения. Новый класс называется дочерним, а тот, у которого он наследует функционал — родительским.
Синтаксис
class BaseClass:
Тело родительского класса
class DerivedClass(BaseClass):
Тело дочернего класса
Особенность наследования заключается в том, что оно позволяет не просто создать дубликат класса, но и расширить его функционал. Это очень полезно, потому что наследование позволяет повторно использовать уже написанный код.
Пример использования наследования
Полигон — замкнутая геометрическая фигура. У полигона 3 и более сторон.
Давайте объявим класс Polygon:
class Polygon:
def __init__(self, no_of_sides):
self.n = no_of_sides
self.sides = [0 for i in range(no_of_sides)]
def inputSides(self):
self.sides = [float(input("Введите сторону " + str(i+1)+ " : ")) for i in range(self.n)]
def dispSides(self):
for i in range(self.n):
print("Сторона", i+1, " — ", self.sides[i])
В этом классе объявлено несколько переменных. Одна хранит количество сторон — n. Вторая, sides — это список, в нём находятся размеры сторон.
Метод inputSides() принимает размер каждой стороны, а dispSides() выводит их на экран.
Треугольник — это полигон с 3 сторонами. Теперь мы можем создать класс Triangle, который наследует весь функционал Polygon. Благодаря этому все атрибуты класса Polygon становятся доступны в Triangle.
Так что нам не нужно объявлять все переменные и методы снова. Давайте создадим класс Triangle:
class Triangle(Polygon):
def __init__(self):
Polygon.__init__(self,3)
def findArea(self):
a, b, c = self.sides
# Вычисляем полупериметр
s = (a + b + c) / 2
area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
print('Площадь треугольника равна %0.2f' %area)
В классе есть и собственный метод findArea(). Он вычисляет площадь треугольника и выводит ее на экран. Попробуем запустить нашу программу:
>>> t = Triangle()
>>> t.inputSides()
Введите сторону 1 : 3
Введите сторону 2 : 5
Введите сторону 3 : 4
>>> t.dispSides()
Сторона 1 — 3.0
Сторона 2 — 5.0
Сторона 3 — 4.0
>>> t.findArea()
Площадь треугольника равна 6.00
Как видите, мы не объявляли методы inputSides() и dispSides() в классе Triangle. Но вот использовать их мы можем!
Если какой-либо атрибут не найдется в дочернем классе, Python пойдет искать в родительской. Этот поиск происходит рекурсивно, если родительский класс одного класса является дочерним для другого.
Переопределение методов
Стоит заметить, что в примере метод __init__() был объявлен в обоих классах — и в Triangle, и в Polygon. Здесь и происходит переопределение классов. То есть, метод в дочернем классе переопределяет тот же самый метод из родительского класса. Это значит, что __init__() в Triangle становится предпочтительнее __init__() в Polygon.
При переопределении метода родительского класса нужно стремиться к его расширению, а не простому копированию. Это, например, происходит при вызове метода в родительском классе из дочернего (вызов Polygon.__init__() из __init__() в Triangle).
Лучше всего использовать встроенную функцию super(). Например, super().__init__(3) эквивалентно вызову Polygon.__init__(self, 3). Старайтесь использовать именно этот способ.
Проверка наследования
Для проверки наследования можно использовать две функции: isinstance() и issubclass().
Функция isinstance() возвращает True, если объект является экземпляром класса или других производных от него классов. Каждый класс в Python является дочерним для какого-либо базового класса.
>>> isinstance(t, Triangle)
True
>>> isinstance(t, Polygon)
True
>>> isinstance(t, int)
False
>>> isinstance(t, object)
True
subclass() же используется для проверки, наследуется ли какой-либо класс от другого.
>>> issubclass(Polygon, Triangle)
False
>>> issubclass(Triangle, Polygon)
True
>>> issubclass(bool, int)
True
Закрепите практикой
Задачи с автоматической проверкой — решайте прямо здесь, не уходя из учебника.