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

Коротко об истории вопроса. ООП полностью понимают всего несколько человек в мире, но, в отличие от теории относительности, каждый по своему.

ООАнализ - ООДизайн - ООПроектирование

ООПрограммирование - кодирование на ОО-языке.

С точки зрения объектно-ориентированного подхода объект -- нечто, обладающее значением (состоянием), типом (поведением) и индивидуальностью. Когда мы выделяем объекты, мы обычно абстрагируемся (отвлекаемся) от большинства их свойств, концентрируясь на существенных для нашей задачи свойствах.

Абстракция

Когда мы выделяем объекты, мы обычно абстрагируемся (отвлекаемся) от большинства их свойств, концентрируясь на существенных для нашей задачи свойствах. Абстрагирование -- один из ключевых принципов объектно-ориентированного подхода:

class Switch:
  """класс Выключатель"""
  def __init__(self, initial_state): self._state = initial_state
  def on(self): self._state = 1
  def off(self): self._state = 0
  def toggle(self): self._state = not self._state

Класс -- множество объектов, имеющих общую структуру и поведение.

Экземпляры класса -- объекты. Объект-класс записывается в программе на Python с помощью ключевого слова class.

Путь "сокрытия данных": функции, модули, объекты (эволюция к более целостным структурам от менее целостных, от менее связных к более связным)

Инкапсуляция. Общедоступные, защищенные и приватные методы (В Python-объектах все атрибуты по умолчанию общедоступны. Приватные методы можно получить, если имя атрибута на два подчеркивания):

class A:
  def m(self):
    return None
  l = 5
  def _internal(self):
    pass
  def __prvt(self):
    pass

Одна и та же функция может работать с разными типами данных. Например, len() одинаково хорошо работает со списками, с классом:

class P:
  def __len__(self): return self.mylen
  def __init__(self, x): self.mylen = len(x)

>>> p = P('222')
>>> len(p)
3

Это называется Полиморфизм ("многоформие"). В Python имеет место т.н. Сигнатурный полиморфизм. То есть, чтобы принадлежать некоторому типу объект должен иметь определенный набор атрибутов и аргументов/результатов этих методов. Выше был описан класс, Роль которого - иметь длину.

Соответственно, достаточно написать объект, подходящий на некоторую Роль, чтобы затем его можно было везде использовать. Пример: файловый и файло-подобный объект. Библиотека, написанная для файлового объекта скорее всего будет так же хорошо работать и с файлоподобным объектом.

Получение одних классов (объектов) от других:

Порождающие функции (функции-фабрики)

Пример:

f = open("FILENAME")
f.write('123')
f.flush()
f.close()

Наследование. Множественное наследование. Mix-in

Один класс наследует все атрибуты другого (других) классов. Пример:

class P1(P):
  def incr(self, x): self.mylen = self.mylen + x

Mix-in (смесь) - класс-химера, состоящий из непересекающихся наборов атрибутов с помощью множественного наследования. Обычно используется в GUI-объектах или в сетевых агентах. Не злоупотреблять!

Агрегация

Возможность помещать одни объекты в другие. Если основной задачей объекта является хранение (и манипуляция) другими объектами, он называется Контейнером.

Объекты Python "живы" пока работает программа-интерпретатор. Чтобы сохранить объекты после этого времени (то есть, получить Устойчивые объекты) необходима Сериализация объектов. Она возможна, например, с помощью встроенного модуля pickle.

Кстати, структуру (Си) или запись (Паскаля) легко эмулировать пустым классом:

class S: pass

s1 = S()
s1.x = 1
s1.y = 2
print (s1.x, s1.y)

Кстати-2, Python - очень динамический язык. В нем можно добавлять атрибуты к объекту/классу по ходу исполнения программы!