Наталья Кайда 17 апреля 2023

🐍 Самоучитель по Python для начинающих. Часть 18: Основы ООП – инкапсуляция и наследование

Рассмотрим базовые понятия (классы, подклассы и методы) и приступим к изучению первых двух фундаментальных принципов объектно-ориентированного программирования. В конце статьи – 10 заданий, связанных с инкапсуляцией и наследованием.
🐍 Самоучитель по Python для начинающих. Часть 18: Основы ООП – инкапсуляция и наследование

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

Объекты, в свою очередь, являются экземплярами классов – с этой точки зрения классы можно назвать шаблонами для создания объектов определенного типа. Классы определяют:

  • структуру данных, которые характеризуют объект;
  • свойства (атрибуты) и статус (состояние) объекта;
  • операции, которые можно совершать с данными объекта (методы).

В этом примере класс Car (автомобиль) имеет атрибуты make, model, year (марка, модель, год выпуска):

        class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    

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

        my_car = Car("Toyota", "Corolla", 2023)
    

Теперь, когда атрибутам объекта присвоены значения, можно к ним обращаться – для этого используют выражение название_объекта.атрибут:

        print(f'Марка машины {my_car.make},'
      f'\nмодель {my_car.model},'
      f'\nгод выпуска - {my_car.year}'
      )

    
        Результат:
Марка машины Toyota,
модель Corolla,
год выпуска – 2023

    

Car пример простейшего класса: у него нет ни подклассов, ни методов, кроме обязательного __init__. Метод – это функция, которая определяет поведение объекта. Проиллюстрируем создание метода на примере класса WashingMachine – здесь метод remaining_warranty_time() определяет срок истечения гарантии на стиральную машину:

        import datetime

class WashingMachine:
    def __init__(self, brand, model, purchase_date, warranty_length):
        self.brand = brand
        self.model = model
        self.purchase_date = purchase_date
        self.warranty_length = warranty_length

    def remaining_warranty_time(self):
        today = datetime.date.today()
        warranty_end_date = self.purchase_date + datetime.timedelta(days=self.warranty_length)
        remaining_time = warranty_end_date - today
        if remaining_time.days < 0:
            return "Срок действия гарантии истек."
        else:
            return "Срок действия гарантии истекает через {} дней.".format(remaining_time.days)

# создаем объект стиральной машины
my_washing_machine = WashingMachine("LG", "FH4U2VCN2", datetime.date(2022, 5, 7), 1550)

# вызываем метод для проверки срока истечения гарантии
print(my_washing_machine.remaining_warranty_time())

    

Результат:

        Срок действия гарантии истекает через 1218 дней.
    
🐍🎓 Библиотека собеса по Python
Подтянуть свои знания по Python вы можете на нашем телеграм-канале «Библиотека собеса по Python»
🐍🧩 Библиотека задач по Python
Интересные задачи по Python для практики можно найти на нашем телеграм-канале «Библиотека задач по Python»

Теперь рассмотрим чуть более сложный пример с подклассами и методами. Предположим, что нам нужно разработать CRM для автосалона. В ПО автосалона должен быть класс Vehicle (транспортное средство), который имеет набор атрибутов:

  • марка;
  • модель;
  • год выпуска;
  • стоимость.

Среди методов должна быть операция display_info(), которая отображает информацию о конкретном транспортном средстве, а помимо классов, в ПО необходимо использовать подклассы.

Подкласс – это класс, который наследует все атрибуты и методы родительского класса (также известного как базовый класс или суперкласс), но при этом может иметь дополнительные, свои собственные, атрибуты и методы. Концепцию наследования мы подробнее разберем ниже.

В ПО для автосалона необходимо создать подкласс Car (легковой автомобиль), который наследует все атрибуты и методы класса Vehicle, и при этом имеет дополнительные атрибуты, например количество дверей и стиль кузова. Аналогично, мы можем создать подкласс Truck (грузовик), который наследует все атрибуты и методы класса Vehicle, и к тому же имеет свои атрибуты – длину кузова и тяговую мощность.

В итоге, взаимодействие классов, подклассов и методов будет выглядеть так:

        class Vehicle:
    def __init__(self, make, model, year, price):
        self.make = make
        self.model = model
        self.year = year
        self.price = price

    def display_info(self):
        print(f"Марка: {self.make}"
        f"\nМодель: {self.model}"
        f"\nГод выпуска: {self.year}"
        f"\nСтоимость: {self.price} руб")

class Car(Vehicle):
    def __init__(self, make, model, year, price, num_doors, body_style):
        super().__init__(make, model, year, price)
        self.num_doors = num_doors
        self.body_style = body_style

class Truck(Vehicle):
    def __init__(self, make, model, year, price, bed_length, towing_capacity):
        super().__init__(make, model, year, price)
        self.bed_length = bed_length
        self.towing_capacity = towing_capacity

    

Создадим экземпляры классов и вызовем метод display_info() для вывода информации о них:

        # создаем объект "легковой автомобиль"
car = Car("Toyota", "Camry", 2022, 2900000, 4, "седан")

# создаем объект "грузовик"
truck = Truck("Ford", "F-MAX", 2023, 6000000, "6162", "13 т")

# выводим информацию о легковом автомобиле и грузовике
car.display_info()
truck.display_info()

    

Результат:

        Марка: Toyota
Модель: Camry
Год выпуска: 2022
Стоимость: 2900000 руб
Марка: Ford
Модель: F-MAX
Год выпуска: 2023
Стоимость: 6000000 руб

    

В этом примере используется встроенная функция super(), которая позволяет вызывать методы родительского суперкласса из подкласса. Этот прием позволяет переиспользовать методы и расширять их функциональность. В данном случае вызывается метод инициализации super().__init__, который позволяет применить атрибуты суперкласса к подклассу. При необходимости, помимо унаследованных, можно определить новые свойства, которые относятся только к конкретному подклассу.

Рассмотрим еще один пример – библиотечную программу для хранения информации о книгах и их статусах (есть в наличии, выдана абоненту, получена от абонента и так далее). Здесь класс Book определяет различные характеристики книги – title, author, ISBN, а также задает методы check_out() и check_in(), которые выдают / принимают книги, и сообщают о статусах:

        class Book:
    def __init__(self, title, author, isbn):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.checked_out = False

    def check_out(self):
        if self.checked_out:
            print("Книга находится у абонента.")
        else:
            self.checked_out = True
            print("Выдаем книгу абоненту.")

    def check_in(self):
        if not self.checked_out:
            print("Книга в наличии.")
        else:
            self.checked_out = False
            print("Принимаем книгу в библиотеку.")

    

Создадим объект книги и проверим статусы:

        # создаем объект книги
book1 = Book("Война и мир", "Л.Н. Толстой", "978-0743273565")

# выдаем книгу, проверяем статус
book1.check_out()

# проверяем статус повторно
book1.check_out()

# принимаем книгу от читателя
book1.check_in()

# проверяем статус книги повторно
book1.check_in()

    

Результат:

        Выдаем книгу абоненту.
Книга находится у абонента.
Принимаем книгу в библиотеку.
Книга в наличии.

    

Классы, объекты, атрибуты и методы – самые простые, самые базовые понятия ООП. Эти базовые концепции, в свою очередь, лежат в основе фундаментальных принципов ООП.

***

Отлично! Вы освоили синтаксис классов и базовые концепции ООП.

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

Но ООП — это не просто синтаксис, это целая философия проектирования. В полной версии урока мы глубоко разберем её первые два фундаментальных принципа:

  • Инкапсуляция: Вы научитесь скрывать данные с помощью приватных атрибутов и управлять доступом к ним через геттеры и сеттеры.
  • Наследование: Вы глубже поймете, как строить иерархии классов, переопределять и расширять поведение родительских методов.
  • 10 практических задач, в которых вы с нуля спроектируете свои собственные классы, применяя эти принципы.

Какие сложности у вас возникают при изучении ООП?

 
 

ВАКАНСИИ

Добавить вакансию
Senior Go / Kubernetes Engineer
от 3000 USD до 7000 USD
Middle/Senior C++ HFT разработчик
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

Подпишись

на push-уведомления