Каждый объект хранит свое состояние (для этого у него есть атрибуты) и имеет определенный набор методов. (Синонимы: атрибут, поле, слот, объект–член, переменная экземпляра). Методы определяют поведение объекта. Объекты класса имеют общее поведение.
Объекты описываются не индивидуально, а с помощью классов. Класс — объект, являющийся шаблоном объекта. Объект, созданный на основе некоторого класса, называется экземпляром класса. Все объекты определенных пользователем классов являются экземплярами класса. Тем не менее, объекты даже с одним и тем же состоянием могут быть разными объектами. Говорят, что они имеют разную индивидуальность.
В языке Python для определения класса используется оператор class:
Листинг
class имя_класса(класс1, класс2, …):
# определения методов
Класс определяет тип объекта, то есть его возможные состояния и набор операций.
Абстракция и декомпозиция
Абстракция в ООП позволяет составить из данных и алгоритмов обработки этих данных объекты, отвлекаясь от несущественных (на некотором уровне) с точки зрения составленной информационной модели деталей. Таким образом, программа подвергается декомпозиции на части «дозированной» сложности. Отдельный объект, даже вместе с совокупностью его связей с другими объектами, человеком воспринимается легче (именно так он привык оперировать в реальном мире), чем что–то неструктурированное и монотонное.
Перед тем как начать написание даже самой простенькой объектно–ориентированной программы, необходимо провести анализ предметной области, для того чтобы выявить в ней классы объектов.
При выделении объектов необходимо абстрагироваться (отвлечься) от большинства присущих им свойств и сконцентрироваться на свойствах, значимых для задачи..
Выделяемые объекты необязательно должны походить на физические объекты — ведь это абстракции, за которыми скрываются процессы, взаимодействия, отношения.
Удачная декомпозиция стоит многого. От нее зависят не только количественные характеристики кода (быстродействие, занимаемая память), но и трудоемкость дальнейшего развития и сопровождения. При отсутствии соответствующего опыта лучше не загадывать будущих путей развития программы, а делать ее как можно проще, под конкретную задачу.
Даже если просто перечислить все существительные, встретившиеся в описании задачи (явно или неявно), получится неплохой список кандидатов в классы.
При процедурном подходе тоже используется декомпозиция, но при объектно–ориентированном подходе производится декомпозиция не самого алгоритма на более мелкие части, а предметной области на классы объектов.
Объекты
До этой лекции объекты Python встречались много раз: ведь каждое число, строка, функция, модуль и т.п. — это объекты. Некоторые встроенные объекты имеют в Python синтаксическую поддержку (для задания литералов). Таковы числа, строки, списки, кортежи и некоторые другие типы.
Теперь следует посмотреть на них в свете только что приведенных определений. Пример:
Листинг
a = 3
b = 4.0
c = a + b
Здесь происходит следующее. Сначала имя «a» связывается в локальном пространстве имен с объектом–числом 3 (целое число). Затем «b» связывается с объектом–числом 4.0 (число с плавающей точкой). После этого над объектами 3 и 4.0 выполняется операция сложения, и имя «c» связывается с получившимся объектом. Кстати, операциями, в основном, будут называться методы, которые имеют в Python синтаксическую поддержку, в данном случае — инфиксную запись. То же самое можно записать как:
Листинг
c = a.__add__(b)
Здесь __add__ - метод объекта a, который реализует операцию + между этим объектом и другим объектом.
Узнать набор методов некоторого объекта можно с помощью встроенной функции dir:
Листинг
>>> dir(a)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__',
'__delattr__', '__div__', '__divmod__', '__doc__', '__float__',
'__floordiv__', '__getattribute__', '__getnewargs__', '__hash__',
'__hex__', '__init__', '__int__', '__invert__', '__long__',
'__lshift__', '__mod__', '__mul__', '__neg__', '__new__',
'__nonzero__', '__oct__', '__or__', '__pos__', '__pow__',
'__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__',
'__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__',
'__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__',
'__rshift__', '__rsub__', '__rtruediv__', '__rxor__',
'__setattr__', '__str__', '__sub__', '__truediv__', '__xor__']
Здесь стоит указать на еще одну особенность Python. Не только инфиксные операции, но и встроенные функции ожидают наличия некоторых методов у объекта. Например, можно записать:
Листинг
abs(c)
А функция abs на самом деле использует метод переданного ей объекта:
Листинг
c.__abs__
Объекты появляются в результате вызова функций–фабрик или конструкторов классов (об этом ниже), а заканчивают свое существование при удалении последней ссылки на объект. Оператор del удаляет имя (а значит, и одну ссылку на объект) из пространства имен:
Листинг
a = 1
# …
del a
# имени a больше нет
Типы и классы