+--------------------------+
|.------------------------.|
|| kee_reel@blog:~$ cd    ||
|| си python терминал     ||
|| opengl sql             ||
||                        ||
||                обо_мне ||
|.------------------------.|
+-::--------------------::-+
.--------------------------.
 // /ooooooooooooooooooooo\\ \\ 
 // /ooooooooooooooooooooooo\\ \\ 
//------------------------------\\
\\------------------------------//

Python. Принципы ООП

В объектно-ориентированном программировании есть 3 основных принципа:

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

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

Чтобы узнать более подробно перейди к отдельной статье про наследование.

Инкапсуляция

Позволяет скрыть детали реализации.

Чтобы узнать более подробно перейди к отдельной статье про инкапсуляцию.

Полиморфизм

Позволяет единообразно работать с методами разных классов, наследованных от одного родительского класса.

Чтобы узнать более подробно перейди к отдельной статье про полиморфизм.

Задание на закрепление “Игра: Симулятор карантина”

Создай класс Person (человек), в нём должны быть:

  • Поле __happiness – при создании объекта равно 10
  • Поле __hunger – при создании объекта равно 50
  • Поле __toilet – при создании объекта равно 100
  • Поле __sleep – при создании объекта равно 100
  • Метод play_computer_games():
    • __happiness + 10
    • __hunger - 10
    • __toilet - 10
    • __sleep - 15
  • Метод eat_something():
    • __happiness + 10
    • __hunger + 30
    • __toilet - 20
    • __sleep - 5
  • Метод do_the_thing():
    • __happiness + 5
    • __hunger - 5
    • __toilet + 100
    • __sleep - 5
  • Метод take_a_nap():
    • __happiness - 5
    • __hunger - 5
    • __toilet - 5
    • __sleep + 5
  • Метод show_stats() – выводит все параметры человека

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

Создай иерархию классов:

  • Родительский класс Room (комната):
    • Строковое поле name – название комнаты
    • Метод spend_time(person) – принимает на вход объект класса Person, никак не взаимодействует с объектом (можно написать pass)
    • Метод print_action(person) – Выводит какую комнату мы сейчас посещаем и текущие параметры (show_stats())
  • Наследованный от Room класс LivingRoom (гостинная):
    • Переопределяет метод spend_time(person) – вызывает у person метод play_computer_games() и print_action() у себя
  • Наследованный от Room класс Kitchen (кухня):
    • Переопределяет метод spend_time(person) – вызывает у person метод eat_something() и print_action() у себя
  • Наследованный от Room класс Toilet (туалет):
    • Переопределяет метод spend_time(person) – вызывает у person метод do_the_thing() и print_action() у себя
  • Наследованный от Room класс Bedroom (спальня):
    • Переопределяет метод spend_time(person) – вызывает у person метод take_a_nap() и print_action() у себя

Конструкторы всех классов, кроме Room не принимают параметров. Прокинь название комнаты в вызов конструктора базового класса:

class Bedroom(Room):
  def __init__(self):
      Room.__init__(self, 'Спальня')
  ...

Мы ещё не касались этого, но в Python можно считывать с клавиатуры значение:

print('Введите число:')
num = input() # Пишу на клавиатуре 42
print(f'Вы ввели число {num}') # Вывод: Вы ввели число 42

Однако, input() возвращает строковое значение, и нам надо превратить его в числовое – для этого надо воспользоваться явным приведением к типу:

num = int(input())

Теперь в num будет нормальное число. А зачем это? Это нужно для задания.

После того, как ты опишешь все классы, исполни этот код:

person = Person()
rooms = [LivingRoom(), Kitchen(), Toilet(), Bedroom()]

print('Текущее состояние персонажа:')
person.show_stats()
print('Твоя задача - пережить карантин!')

for i in range(25, 0, -1):
    print(f'''Осталось {i} часов
В какую комнату пойти?
1 - Гостинная
2 - Кухня
3 - Туалет
4 - Спальня''')
    room_num = int(input()) - 1
    room = rooms[room_num]
    room.spend_time(person)
    person.show_stats()

print('Ура, ты выжил!')

Если всё запустилось, то можешь поиграть в СВОЮ игру!

Как наиграешься, добавь такие функции:

  • Добавь ограничение в 100 во всех показателях (в методах у Person), чтобы оно не выходило за пределы
  • Добавь какой-то метод в Person, чтобы он проверял не опустилось ли значение любого из показателей ниже нуля – если опустилось, то прерви игру и сообщи игроку “Ты не пережил карантин”

Заключение

Вот это была прям босс-статья – много кода, много нового!

Итого, мы изучили:

  • Наследование (родительский класс, дочерний класс, конструктор родительского класса, переопределение метода)
    • Тебе не надо дублировать одинаковую логику в разных классах – логика пишется один раз в родительском классе, и переиспользуется во всех дочерних классах
  • Инкапсуляция (приватное поле, приватный метод)
    • Если ты хочешь чтобы твой код не ломался при изменении внутренней логики – надо использовать инкапсуляцию, и скрывать как можно больше кода от шаловливых ручек программистов
  • Полиморфизм
    • Благодаря полиморфизму, ты можешь вызывать один и тот же метод для разных классов

Если что – пиши, я помогу и постараюсь объяснить лучше.

Поздравляю 🥳

Мы изучили все основы, и дальше начнём изучать инструменты, которые расширят наши возможности за пределы программы:

  • Файлы
  • База данных
  • Telegram бот
  • Веб-сервер