Переопределение методов
Дочерний класс может заменить метод родителя целиком — или дополнить его через super().
Переопределение: свой вариант метода родителя
Дочерний класс может определить метод с ТЕМ ЖЕ именем, что и у родителя — это называется переопределением (override). Python при поиске метода находит версию дочернего класса первой (раздел 14.16, MRO) и использует именно её:
class Zhivotnoe:
def zvuk(self):
print("Какое-то животное издаёт звук")
class Sobaka(Zhivotnoe):
def zvuk(self): # полностью заменяет родительскую версию
print("Гав!")
Sobaka().zvuk() # Гав! — версия Zhivotnoe даже не вызывается
Иногда нужно не полностью заменить поведение родителя, а ДОПОЛНИТЬ его — тогда
переопределённый метод вызывает super().метод() и добавляет
что-то своё:
class Zhivotnoe:
def zvuk(self):
print("Животное подаёт голос:")
class Sobaka(Zhivotnoe):
def zvuk(self):
super().zvuk() # сначала родительская часть
print("Гав!") # затем своя
Sobaka().zvuk()
# Животное подаёт голос:
# Гав!
class Zhivotnoe:
def zvuk(self):
print("Животное подаёт голос:")
class Sobaka(Zhivotnoe):
def zvuk(self):
print("Гав!") # хотели ДОПОЛНИТЬ, но случайно заменили целиком
Sobaka().zvuk()
>>> Sobaka().zvuk()
Гав!
Строка «Животное подаёт голос:» пропала — переопределение по умолчанию ЗАМЕНЯЕТ родительский метод целиком, а не дополняет его автоматически. Если задумывалось именно дополнение, вызов super().zvuk() нужно прописать явно — Python никогда не вызывает родительскую версию сам, если вы её не попросили.
class Sobaka(Zhivotnoe):
def zvuk(self):
super().zvuk()
print("Гав!")