Наследование в 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.

Как видите, мы не объявляли методы 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
codechick

СodeСhick.io - простой и эффективный способ изучения программирования.

2024 ©