Лекция 8. ООП. Классы, атрибуты, объекты, методы
ООП — самая используемая парадигма программирования. Это одновременно и особый способ мышления, и отдельная методика. Её концепцию проще всего понимать на примерах из реальной жизни. И это неспроста. Объектно-ориентированное программирование помогает представлять содержимое программы наиболее естественным для нашего мира способом.
Главным понятием ООП является понятие программного объекта. Вообще говоря, большинство сущностей на планете Земля — это некие объекты. И с частью из них мы взаимодействуем при помощи программирования. Банковский счёт, персонаж компьютерной игры или анимированный виджет сайта — всё это легко представить в виде объектов. Можно сказать, что объектно-ориентированное программирование позволяет смоделировать реальный объект в виде программного.
Множество объектов со схожими свойствами формируются в классы. Идея класса также является одной из основополагающих концепций ООП. Со стороны программы, класс — это всего лишь тип данных, но для программиста это куда более глубокая абстрактная структура. Но перейдём уже к конкретике.
Итак, мы — разработчики игр. Наша студия трудится над новым автосимулятором. В игре будут представлены разные виды транспорта: легковые автомобили, гоночные, грузовые и пассажирские. Все их можно описать одним словом — автотранспорт. Сделав это, мы абстрагировались от деталей и, таким образом, определили класс. Объектом этого класса может быть, как Бьюик 1968-го года, так и грузовой Freightliner Columbia желтого цвета.
У класса есть свойства и функции (в ООП их называют методами).
Свойства — это характеристики, присущие данному конкретному множеству объектов.
Методы — те действия, которые они могут совершать.
Свойствами класса "автотранспорт" могут быть, например: год выпуска, вид и цвет. На уровне объектов это будет выглядеть так: Бьюик Электра — это объект класса "Автотранспорт" со следующими свойствами:
вид — легковой автомобиль;
цвет — чёрный;
год выпуска — 1968.
Можно сказать, что объект — это вполне конкретный экземпляр класса.
Помимо физических атрибутов, которые описывают внешний вид и характеристики транспортного средства, автомобили обладают между собой и другими фундаментальными сходствами. Например, все они могут ехать, тормозить, переключать скорости, поворачивать и сигналить. В нашем случае, всё это — методы класса "Автотранспорт". То есть действия, которые любые объекты данного класса могут выполнять.
Мы разрабатываем игру, поэтому предполагается, что машины в ней будут исправными. Значит, вполне естественно, что каждая из них может ехать и тормозить.
В Питоне класс "Автотранспорт" может выглядеть так:
# класс автотранспорт
class MotorTransport(object):
def __init__(self, color, year, auto_type):
self.color = color
self.year = year
self.auto_type = auto_type
# тормозить
def stop(self):
print("Pressing the brake pedal")
# ехать
def drive(self):
print('WRRRRRUM!')
Теперь никто не помешает нам получить собственную красную феррари. Пусть и в симуляторе.
# создадим объект класса Автотранспорт
ferrari_testarossa = MotorTransport('Red', 1987, 'passenger car')
# жмём на газ и вперёд!
ferrari_testarossa.drive()
WRRRRRUM!
Класс
Классы, в некотором смысле, подобны чертежам: это не объекты сами по себе, а их схемы. Класс "банковских счетов" имеет строго определенные и одинаковые для всех атрибуты, но объекты в нём — сами счета — уникальны.
Как в Python создать класс
В Python классы и объекты по смыслу не отличаются от других языков. Нюансы в реализации. Для создания класса в Питоне необходимо написать инструкцию class, а затем выбрать имя.
В простейшем случае, класс выглядит так:
class SimpleClass:
pass
Для именования классов в Python обычно используют стиль "camel case", где первая буква — заглавная.
LikeThis
Конструктор
Метод, который вызывается при создании объектов, в ООП зовётся конструктором. Он нужен для объектов, которые изначально должны иметь какие-то значение. Например, пустые экземпляры класса "Студент" бессмысленны, и желательно иметь хотя бы минимальный обозначенный набор вроде имени, фамилии и группы.
В качестве Питоновского конструктора выступает метод __init__():
class Student:
def __init__(self, name, surname, group):
self.name = name
self.surname = surname
self.group = group
alex = Student("Alex", "Ivanov", "admin")
Атрибуты класса
Вы уже поняли, что у каждого класса есть собственный набор характеристик, который помогает описывать его сущность. Эти свойства еще называются полями или атрибутами.
Поля могут быть статическими и динамическими:
Статические поля (поля класса) можно использовать без создания объекта. А значит, конструктор вам не нужен.
Динамические поля (поля объекта) задаются с помощью конструктора, и тут уже, как вы видели, экземпляр нужно создать, а полям присвоить значения.
class MightiestWeapon:
# статический атрибут
name = "Default name"
def __init__(self, weapon_type):
# динамический атрибут
self.weapon_type = weapon_type
Обратите внимание — статический и динамический атрибут может иметь одно и то же имя:
class MightiestWeapon:
# статический атрибут
name = "Default name"
def __init__(self, name):
# динамический атрибут
self.name = name
weapon = MightiestWeapon("sword")
print(MightiestWeapon.name)
print(weapon.name)
Методы класса
Метод — это функция класса.
Например, у всех научно-фантастических космических кораблей есть бортовое оружие. И оно может стрелять.
class SpaceShip:
def atack(self):
print('Пиу!')
star_destroyer = SpaceShip()
star_destroyer.atack()
Пиу!
Что такое self?
Аналог этого ключевого слова в других языках — слово this. self — это всего лишь ссылка на текущий экземпляр класса.
Отличный пример с котофеями:
Все котики умеют мурлыкать;
Эта способность реализована в классе Кот, как метод Мурчать;
Вы хотите, чтобы ваш кот по имени Пушок помурчал;
Если сделать так: Кот.Мурчать, то мурлыкать начнут все коты во Вселенной;
Но так как вам нужен один конкретный кот, то нужно вызвать метод иначе: self.Мурчать;
Сделано. Пушок мурлыкает.
Уровни доступа атрибутов и методов
В Питоне не существует квалификаторов доступа к полям класса. Отсутствие аналогов связки public/private/protected можно рассматривать как упущение со стороны принципа инкапсуляции.
Декораторы
Декоратор — это функция-обёртка. В неё можно завернуть другой метод, и, тем самым, изменить его функциональность, не меняя код.
Объекты или экземпляры класса
Чем объекты отличаются от классов
Как уже было сказано, объект — это конкретный экземпляр класса. Все мы относимся к классу людей, но каждый из нас — уникальный объект этого класса.
Как создать объект класса в Python
Если у нас есть реализация класса, то его экземпляр создать очень просто:
class AirConditioner:
def __init__(self, model, capacity):
self.model = model
self.capacity = capacity
def turn_on(self):
print('Now in the room will be cool')
# создадим объект класса Кондиционер
ballu = AirConditioner('BPAC-07', 785)
ballu.turn_on()
Now in the room will be cool
Атрибуты объекта
Атрибуты класса могут быть динамическими и статическими. На уровне объекта они инициализируются так:
class MightiestWeapon:
name = "Default name"
def __init__(self, weapon_type):
self.weapon_type = weapon_type
# атрибут name можно переопределить и не создавая объекта
MightiestWeapon.name = 'Steel Sword'
print(MightiestWeapon.name)
Steal Sword
# создаём объект и сразу же инициализируем динамический атрибут с помощью конструктора
hero_sword = MightiestWeapon('sword')
# и теперь, уже для конкретного объекта, можно задать имя
hero_sword.name = 'Excalibur'
# новое статическое имя по умолчанию для всего класса не изменится
print(MightiestWeapon.name)
Steal Sword
print(hero_sword.name)
Excalibur