Python. Принципы ООП
Время чтения: 3 минут
В объектно-ориентированном программировании есть 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 бот
- Веб-сервер