
Лекция.
Объектно-ориентированное программирование.

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

Чем же хорош подход ООП?
- Программа разбивается на объекты. Каждый объект отвечает за собственные данные и их обработку. Как результат - код становится проще и читабельней.
- Уменьшается дупликация кода. Нужен новый объект, содержимое которого на 90% повторяет уже существующий? Давайте создадим новый класс и унаследуем эти 90% функционала от родительского класса!
- Упрощается и ускоряется процесс написания программ. Можно сначала создать высокоуровневую структуру классов и базовый функционал, а уже потом перейти к их подробной реализации.

Объекты и классы в ООП
Класс
— в объектно-ориентированном программировании, представляет собой шаблон для создания объектов, обеспечивающий начальные значения состояний: инициализация полей-переменных и реализация поведения функций или методов.
Объект
— некоторая сущность в цифровом пространстве, обладающая определённым состоянием и поведением, имеющая определенные свойства (поля) и операции над ними (методы). Как правило, при рассмотрении объектов выделяется то, что объекты принадлежат одному или нескольким классам, которые определяют поведение (являются моделью) объекта. Термины «экземпляр класса» и «объект» взаимозаменяемы.

На что необходимо обратить внимание?
- Класс описывает множество объектов, имеющих общую структуру и обладающих одинаковым поведением. Класс - это шаблон кода, по которому создаются объекты. Т. е. сам по себе класс ничего не делает, но с его помощью можно создать объект и уже его использовать в работе.
- Данные внутри класса делятся на свойства и методы. Свойства класса (они же поля) - это характеристики объекта класса.
- Методы класса - это функции, с помощью которых можно оперировать данными класса.
- Объект - это конкретный представитель класса.
- Объект класса и экземпляр класса - это одно и то же.
Грубо говоря
Класс = Свойства + Методы

Простой пример ООП
Свойства класса
- Цвет
- Объем двигателя
- Мощность
- Тип коробки передач
Методы класса
- Ехать
- Остановиться
- Заправиться
- Поставить на сигнализацию
- Включить дворники
Грубо говоря
Класс = Свойства + Методы

Простой пример ООП
# класс автотранспорт
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!

Синтаксис создания
class :
Создание класса
Для задания класса используется инструкция class, далее следует имя класса Car и двоеточие. После них идет тело класса, которое в нашем случае представлено оператором pass . Данный оператор сам по себе ничего не делает - фактически это просто заглушка.
class Car:
pass
Создание объекта
= ()
В качестве примера создадим объект класса Car :
car _ object = Car()

Основы ООП на Python для начинающих
Создавать классы в Python очень просто:
class SomeClass(object):
# поля и методы класса SomeClass
Классы-родители перечисляются в скобках через запятую:
class SomeClass(ParentClass1, ParentClass2, …):
# поля и методы класса SomeClass
class SomeClass(object):
attr1 = 42
attr2 = "Hello, World"
Свойства классов устанавливаются с помощью простого присваивания:
class SomeClass(object):
def method1(self, x):
# код метода
Методы объявляются как простые функции:

Поля (свойства) класса в Python
Поля(они же свойства или переменные) можно (так же условно) разделить на две группы:
- Статические поля
- Динамические поля

Статические поля (они же переменные или свойства класса)
Это переменные, которые объявляются внутри тела класса и создаются тогда, когда создается класс. Создали класса - создалась переменная:
class Phone:
# Статические поля (переменные класса)
default _ color = 'Grey'
default _ model = ‘C385’
def turn _ on(self):
pass
def call(self):
pass
Phone.default _ color
'Grey'
# Изменяем цвет телефона по умолчанию с серого на черный
Phone.default _ color = 'Black'
Phone.default _ color
'Black'
У нас есть возможность получить или изменить такое свойство, просто обратившись к самому классу по его имени(экземпляр класса при этом создавать не нужно).

Динамические поля (переменные или свойства экземпляра класса)
# Создадим экземпляр класса Phone - телефон красного цвета модели 'I495’
my _ phone _ red = Phone('Red', 'I495')
# Прочитаем статические поля объекта
my _ phone _ red.default _ color
'Grey'
my _ phone _ red.default _ model
'C385'
# Прочитаем динамические поля объекта
my _ phone _ red.color
'Red'
my _ phone _ red.model
'I495'
# Создадим еще один экземпляр класса Phone - такой же телефон, но другого цвета
my _ phone _ blue = Phone('Blue', 'I495')
# Прочитаем динамические поля объекта
my _ phone _ blue.color
'Blue'
my _ phone _ blue.model
'I495'
Это переменные, которые создаются на уровне экземпляра класса. Нет экземпляра - нет его переменных. Для создания динамического свойства необходимо обратиться к self внутри метода:
class Phone:
# Статические поля (переменные класса)
default _ color = 'Grey'
default _ model = 'C385'
def __ init __ (self, color, model):
# Динамические поля (переменные объекта)
self.color = color
self.model = model

Что такое self в Python?
Служебное слово self - это ссылка на текущий экземпляр класса. Как правило, эта ссылка передается в качестве первого параметра метода Python.
Стоит обратить внимание, что на самом деле слово self не является зарезервированным. Просто существует некоторое соглашение, по которому первый параметр метода именуется self и передает ссылку на текущий объект, для которого этот метода был вызван.
Чтоб создать переменную экземпляра, необходимо воспользоваться конструкцией self. _ переменной внутри одного из методов

Уровни доступа атрибутов в Python
- Private. Приватные члены класса недоступны извне - с ними можно работать только внутри класса.
- Public. Публичные методы наоборот - открыты для работы снаружи и, как правило, объявляются публичными сразу по-умолчанию.
- Protected. Доступ к защищенным ресурсам класса возможен только внутри этого класса и также внутри унаследованных от него классов (иными словами, внутри классов-потомков). Больше никто доступа к ним не имеет

Инициализирующий метод
Инициализирующий метод — это специальный метод, который вызывается при создании объекта. Этот метод имеет имя __ init __ (два символа подчеркивания, init, и еще два символа подчеркивания). Инициализирующий метод класса Time выглядит так:
Когда мы создаем объект Time, указанные нами аргументы передаются конструктору:
Метод, вызываемый при создании объекта и инициализирующий состояние объекта, также называют конструктором. В Python метод __ init __ является конструктором.
class Time:
def __ init __ (self, hours=0, minutes=0, seconds=0):
self.hours = hours
self.minutes = minutes
self.seconds = seconds
def __ str __ (self):
return "%02i:%02i:%02i" % (self.hours, self.minutes, self.seconds)
current _ time = Time(9, 14, 30)
print(current _ time)
09:14:30

Метод __ str __
Метод __ str __ имеет специальное назначение в Python, он возвращает строковое представление объекта. Определим метод __ str __ для класса Time.
Если класс предоставляет метод с именем __ str __ , то тем самым переопределяет поведение встроенной функции Python str.
class Time:
def __ init __ (self, hours=0, minutes=0, seconds=0):
self.hours = hours
self.minutes = minutes
self.seconds = seconds
def __ str __ (self):
return "%02i:%02i:%02i" % (self.hours, self.minutes, self.seconds)
t = Time(9)
print(t)
09:00:00

Специальные методы
__ bytes __ ()
__ str __ ()
Метод возвращает объект типа bytes – представление текущего объекта в виде набора байт.
__ repr __ ()
Строковое представление объекта, используемое в функциях format() и print(). В отличии от __ repr __ (), в ней, при реализации, мы стараемся создать наиболее информативное представление объекта.
Строковое представление объекта, позволяющее восстановить объект. Например, если вы пишете игру и у вас есть объект “Персонаж”, которому при его создании присваивается имя и пол, то метод __ repr __ () может вернуть следующую строку “Person(“John”, “man”)”. Эта информация позволит вам заново построить объект.
__ len __ ()
Чаще всего реализуется в коллекциях и сходными с ними по логике работы типами, которые позволяют хранить наборы данных. Для списка (list) __ len __ () возвращает количество элементов в списке, для строки – количество символов в строке. Вызывается функцией len(), встроенной в язык Python.
__ bool __ ()
Возвращает True или False.
__ call __ ()
Позволяет использовать объект как функцию, т.е. его можно вызвать.

Функции сравнения
Эти функции используются, если объекты можно сравнивать между собой, как числа. Синтаксис работы с ними выглядит следующим образом: x. __ lt __ (y), что соответствует записи x

Арифметические операции

Унарные операции
Битовые операции

Примеры
class Vector():
def __ init __ (self, x, y):
self.x = x
self.y = y
def __ add __ (self, v):
return Vector(self.x + v.x, self.y + v.y)
def __ sub __ (self, v):
return Vector(self.x - v.x, self.y - v.y)
def __ repr __ (self):
return "Vector({}, {})".format(self.x, self.y)
def __ str __ (self):
return "({}, {})".format(self.x, self.y)
def __ abs __ (self):
return (self.x**2 + self.y**2)**0.5
if __ name __ == " __ main __ ":
v1 = Vector(3, 4)
print("vector v1 = {}".format(v1))
v2 = Vector(5, 7)
print("vector v2 = {}".format(v2))
print("v1 + v2 = {}".format(v1 + v2))
print("v2 - v1 = {}".format(v2 - v1))
print("|v1| = {}".format(abs(v1)))
vector v1 = (3, 4)
vector v2 = (5, 7)
v1 + v2 = (8, 11)
v2 - v1 = (2, 3)
|v1| = 5.0