JavaRush /Курсы /Модуль 1: Python Core /Наследование

Наследование

Модуль 1: Python Core
9 уровень , 5 лекция
Открыта

6.1 Наследование — это просто

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

Такой подход позволяет создавать более общие классы и повторно использовать код, улучшая организацию и поддерживаемость кода.

Зачем нужно наследование?

Допустим, вам нужно написать какой-то код, и вы решили сделать это в виде класса. Потом вы узнали, что в вашем проекте уже существует класс, который делает почти всё, что нужно вам в вашем классе. Вы можете просто скопировать код этого класса в свой и пользоваться в своё удовольствие.

А можете «как бы скопировать». Вы можете объявить тот класс родителем своего класса, и тогда Python добавит вашему классу поведение класса родителя.

Представьте, что вы природа и хотите создать Собаку. Что будет быстрее — создать собаку из бактерии за миллиард лет или одомашнить волка за 200 тысяч лет?

Пример базового наследования

Допустим, у вас есть родительский класс Animal с полем name:


class Animal:
    def __init__(self, name):
        self.name = name

Мы хотим создать 2 класса-наследника для него — Dog и Cat, а также добавить им обоим метод speak:


class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

В примере выше дочерние классы Dog и Cat наследуют от Animal и добавляют метод speak.

Класс Dog:

  • Наследует атрибут name из Animal.
  • Добавляет метод speak, возвращающий строку, специфичную для собак.

Класс Cat:

  • Наследует атрибут name из Animal.
  • Добавляет метод speak, возвращающий строку, специфичную для кошек.

Финальный вариант кода выглядит так:


class Animal:
    def __init__(self, name):
        self.name = name
         
class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"
        
class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"
         
dog = Dog("Buddy")
cat = Cat("Whiskers")
        
print(dog.speak())  # Выведет: Buddy says Woof!
print(cat.speak())  # Выведет: Whiskers says Meow!

В этом примере Animal является родительским классом, а Dog и Cat — дочерними классами. Дочерние классы наследуют атрибут name и метод __init__ от родительского класса Animal, но добавляют методы speak.

6.2 Под капотом у наследования

Если вы добавили своему классу родителя, то это очень похоже на то, как будто вы скопировали код класса родителя в свой класс.


class Animal:
    def __init__(self, name):
        self.name = name
         

class Dog(Animal):
    def __init__(self, name):
        super().__init__(name)  # Вызов конструктора родительского класса
        
    def speak(self):
        return f"{self.name} says Woof!"
        
class Cat(Animal):
    def __init__(self, name):
        super().__init__(name)  # Вызов конструктора родительского класса
        
    def speak(self):
        return f"{self.name} says Meow!"
        

dog = Dog("Buddy")
cat = Cat("Whiskers")
        
print(dog.speak())  # Выведет: Buddy says Woof!
print(cat.speak())  # Выведет: Whiskers says Meow!

Это не совсем точное описание, но если вы никогда не сталкивались с концепцией наследования, то можете пока думать о ней в таком ключе. Дальше мы добавим сюда ещё деталей.

6.3 Иерархия наследования

Очень часто, когда проектируется сложная модель большой группы классов, вы можете столкнуться с целой иерархией наследования.

Например, у вас есть класс Animal — это базовый класс для всех животных:


class Animal:
    def __init__(self, name):
        self.name = name
        
    def speak(self):
        raise NotImplementedError("Subclass must implement abstract method")

Мы даже добавили ему метод speak, но так как абстрактное животное не говорит, этот метод просто кидает исключение NotImplementedError — это стандартная практика.

Затем мы добавляем промежуточные классы, которые соответствуют категориям животных: Mammal — это млекопитающие и Bird для птиц.


class Mammal(Animal):
    def __init__(self, name, fur_color):
        super().__init__(name)  # Вызов конструктора родительского класса
        self.fur_color = fur_color
         

class Bird(Animal):
    def __init__(self, name, wing_span):
        super().__init__(name)  # Вызов конструктора родительского класса
        self.wing_span = wing_span
        
    def fly(self):
        return f"{self.name} is flying with a wingspan of {self.wing_span} meters."

И наконец, только на финальном этапе появляются классы конкретных видов животных:


class Dog(Mammal):
    def speak(self):
        return f"{self.name} says Woof!"
         
        
class Cat(Mammal):
    def speak(self):
        return f"{self.name} says Meow!"
        
class Parrot(Bird):
    def speak(self):
        return f"{self.name} says Squawk!"

Вот с ними обычно и работает конечный код:


animals = [Dog("Buddy", "brown"), Cat("Whiskers", "white"), Parrot("Polly", 0.5)]
            
for animal in animals:
    print(animal.speak())

print(f"{dog.name} has {dog.fur_color} fur.")  # Выведет: Buddy has brown fur.
print(f"{cat.name} has {cat.fur_color} fur.")  # Выведет: Whiskers has white fur.
print(parrot.fly())  # Выведет: Polly is flying with a wingspan of 0.5 meters.

Хотя технически нет запретов на создание иерархий с десятками предков, важно помнить, что без необходимости лучше придерживаться простоты. В простоте сила.

2
Задача
Модуль 1: Python Core, 9 уровень, 5 лекция
Недоступна
Машины.
Машины.
2
Задача
Модуль 1: Python Core, 9 уровень, 5 лекция
Недоступна
Фигуры.
Фигуры.
1
Опрос
Классы и ООП, 9 уровень, 5 лекция
Недоступен
Классы и ООП
Классы и ООП
Комментарии (9)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Maksym Уровень 22
31 октября 2025
Во второй задаче вам нужна библиотека math, для вычисления площади круга
shinobi Уровень 19
5 августа 2025
Привожу пример трех вопросов из теста "Что показывает пример с муравейником?" "Какова аналогия класса в реальном мире, приведенная в документе?" "Что показывает пример с муравейником?" Какой нахер муравейник? Почему аж два раза один и тот же вопрос? Какой документ? Как же автору было плевать на опрос, на его вопросы и ответы, просто копирка на автомате, настолько лень делать курс, за который потом сотни людей отдавали свои деньги. И курсу не один год уже, кто будет исправлять это говно и халтуру? Никто.
Slevin Уровень 11
2 июля 2025
Площадь круга: math.pi * radius ** 2
Davich Уровень 44
7 июня 2025
Приветствую, возможно кто-то сталкивался с таким, решаю задачи через PyCharm, и нажимаю на кнопку проверки , ничего не происходит, но если открыть задачу через javarush и снова сделать проверку,задачу засчитывает но и засчитывает дваойнную попытку решения.
SWK Уровень 26
7 апреля 2025

Какая роль у 'главного объекта' в программе, согласно документу?
Я даже не интересуюсь, о каком документе идёт речь. И так понятно, что о том, который авторы промптом переводили.
SWK Уровень 26
7 апреля 2025
Вопрос "Какова аналогия класса в реальном мире, приведенная в документе?" ИИ сочинял?
Assator Уровень 23
12 февраля 2025
Я где-то просмотрел объявление переменных dog и cat в последнем листинге?
Mr.Robot Уровень 21 Expert
9 марта 2025
Нет - их и не было. Более того - так работать не будет. Последние 3 строки в таком виде вызывают ошибку. Вот так будет работать:

print(f"{animals[0].name} has {animals[0].fur_color} fur.")  # Выведет: Buddy has brown fur.
print(f"{animals[1].name} has {animals[1].fur_color} fur.")  # Выведет: Whiskers has white fur.
print(animals[2].fly())  # Выведет: Polly is flying with a wingspan of 0.5 meters.
Что-то вроде полиморфного списка, хоть для питона это - оксюморон.
SWK Уровень 26
7 апреля 2025
Просмотрел. Они в предпоследнем.