Python переопределение метода при наследовании

Наследование в 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 . Но вот использовать их мы можем!

Читайте также:  Java discord bot tutorial

Если какой-либо атрибут не найдется в дочернем классе, Python пойдет искать в родительской. Этот поиск происходит рекурсивно, если родительский класс одного класса является дочерним для другого.

Переопределение методов

Стоит заметить, что в примере метод __init__() был объявлен в обоих классах — и в Triangle , и в Polygon . Здесь и происходит переопределение классов. То есть, метод в дочернем классе переопределяет тот же самый метод из родительского класса. Это значит, что __init__() в Triangle становится предпочтительнее __init__() в Polygon .

При переопределении метода родительского класса нужно стремиться к его расширению, а не простому копированию. Это, например, происходит при вызове метода в родительском классе из дочернего (вызов P olygon.__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

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

2023 © ООО «Алгоритмы и практика»

Источник

Полиморфизм в Python

В этой статье мы изучим полиморфизм, разные типы полиморфизма и рассмотрим на примерах как мы можем реализовать полиморфизм в Python.

Что такое полиморфизм?

В буквальном значении полиморфизм означает множество форм.

Полиморфизм — очень важная идея в программировании. Она заключается в использовании единственной сущности(метод, оператор или объект) для представления различных типов в различных сценариях использования.

Давайте посмотрим на пример:

Читайте также:  Ide для php html css

Пример 1: полиморфизм оператора сложения

Мы знаем, что оператор + часто используется в программах на Python. Но он не имеет единственного использования.

Для целочисленного типа данных оператор + используется чтобы сложить операнды.

num1 = 1 num2 = 2 print(num1 + num2)

Итак, программа выведет на экран 3 .

Подобным образом оператор + для строк используется для конкатенации.

str1 = "Python" str2 = "Programming" print(str1+" "+str2)

В результате будет выведено Python Programming .

Здесь мы можем увидеть единственный оператор + выполняющий разные операции для различных типов данных. Это один из самых простых примеров полиморфизма в Python.

Полиморфизм функций

В Python есть некоторые функции, которые могут принимать аргументы разных типов.

Одна из таких функций — len() . Она может принимать различные типы данных. Давайте посмотрим на примере, как это работает.

Пример 2: полиморфизм на примере функции len()

print(len("Programiz")) print(len(["Python", "Java", "C"])) print(len())

Здесь мы можем увидеть, что различные типы данных, такие как строка, список, кортеж, множество и словарь могут работать с функцией len() . Однако, мы можем увидеть, что она возвращает специфичную для каждого типа данных информацию.

Полиморфизм функции len()

Полиморфизм в классах

Полиморфизм — очень важная идея в объектно-ориентированном программировании.

Чтобы узнать больше об ООП в Python, посетите эту статью: Python Object-Oriented Programming.

Мы можем использовать идею полиморфизма для методов класса, так как разные классы в Python могут иметь методы с одинаковым именем.

Позже мы сможем обобщить вызов этих методов, игнорируя объект, с которым мы работаем. Давайте взглянем на пример:

Пример 3: полиморфизм в методах класса

class Cat: def __init__(self, name, age): self.name = name self.age = age def info(self): print(f"I am a cat. My name is . I am years old.") def make_sound(self): print("Meow") class Dog: def __init__(self, name, age): self.name = name self.age = age def info(self): print(f"I am a dog. My name is . I am years old.") def make_sound(self): print("Bark") cat1 = Cat("Kitty", 2.5) dog1 = Dog("Fluffy", 4) for animal in (cat1, dog1): animal.make_sound() animal.info() animal.make_sound()
Meow I am a cat. My name is Kitty. I am 2.5 years old. Meow Bark I am a dog. My name is Fluffy. I am 4 years old. Bark

Здесь мы создали два класса Cat и Dog . У них похожая структура и они имеют методы с одними и теми же именами info() и make_sound() .

Читайте также:  Methods in java util arraylist

Однако, заметьте, что мы не создавали общего класса-родителя и не соединяли классы вместе каким-либо другим способом. Даже если мы можем упаковать два разных объекта в кортеж и итерировать по нему, мы будем использовать общую переменную animal . Это возможно благодаря полиморфизму.

Полиморфизм и наследование

Как и в других языках программирования, в Python дочерние классы могут наследовать методы и атрибуты родительского класса. Мы можем переопределить некоторые методы и атрибуты специально для того, чтобы они соответствовали дочернему классу, и это поведение нам известно как переопределение метода(method overriding).

Полиморфизм позволяет нам иметь доступ к этим переопределённым методам и атрибутам, которые имеют то же самое имя, что и в родительском классе.

Давайте рассмотрим пример:

Пример 4: переопределение метода

from math import pi class Shape: def __init__(self, name): self.name = name def area(self): pass def fact(self): return "I am a two-dimensional shape." def __str__(self): return self.name class Square(Shape): def __init__(self, length): super().__init__("Square") self.length = length def area(self): return self.length**2 def fact(self): return "Squares have each angle equal to 90 degrees." class Circle(Shape): def __init__(self, radius): super().__init__("Circle") self.radius = radius def area(self): return pi*self.radius**2 a = Square(4) b = Circle(7) print(b) print(b.fact()) print(a.fact()) print(b.area())
Circle I am a two-dimensional shape. Squares have each angle equal to 90 degrees. 153.93804002589985

Здесь мы можем увидеть, что такие методы как __str__() , которые не были переопределены в дочерних классах, используются из родительского класса.

Благодаря полиморфизму интерпретатор питона автоматически распознаёт, что метод fact() для объекта a (класса Square ) переопределён. И использует тот, который определён в дочернем классе.

С другой стороны, так как метод fact() для объекта b не переопределён, то используется метод с таким именем из родительского класса( Shape ).

Полиморфизм на примере дочерних и родительских классов в питоне

Заметьте, что перегрузка методов(method overloading) — создание методов с одним и тем же именем, но с разными типами аргументов не поддерживается в питоне.

Источник

Оцените статью