Добавлен: 31.03.2023
Просмотров: 100
Скачиваний: 2
Большая часть конструирования объектно-ориентированных прикладных программ состоит в построении иерархии объектов, являющейся отражением генеалогического дерева объектов в приложениях.
Как показали данные определения, объекты тесно связаны с записями. Новое зарезервированное слово object является наиболее очевидным различием, но как мы увидим позднее, имеется большое число других различий, некоторые из которых довольно тонкие.
3.3. Экземпляры объектных типов
Экземпляры объектных типов описываются в точности так же, как в Паскале описывается любая переменная, либо статическая, либо указатель, ссылающийся на размещенную в динамической памяти переменную.
Мы можем обратиться к полю объекта в точности так же, как к полю обычной записи, либо с помощью оператора with, либо путем уточнения имени с помощью точки.
Даже если мы можем обратиться к полям объекта непосредственно, это будет не совсем хорошей идеей. Принципы объектно-ориентированного программирования требуют, чтобы поля объектов были исключены из исходного кода, насколько это возможно. Это ограничение поначалу может показаться спорным и жестким, но оно является только частью огромной картины объектно-ориентированное программирования.
Ответ заключается в том, что при всякой возможности для доступа к полям данных должны использоваться методы объекта. Метод является процедурой или функцией, описанной внутри объекта и жестко ограниченной этим объектом.
Методы являются одними из наиболее примечательных атрибутов объектно-ориентированного программирования и требуют некоторой практики перед использованием.
Метод - это процедура или функция, объединенная с данным типом столь тесно, что метод является как бы окруженным невидимым оператором with, что делает экземпляр данного типа доступными изнутри для метода. Определение типа включает заголовок метода. Полное определение метода квалифицируется в имени типа. Тип объекта и метод объекта являются двумя лицами этой новой разновидности структуры, именуемой методом.
Одним из важнейших принципов объектно-ориентированного программирования является то, что программист во время разработки программы должен думать о коде и о данных совместно. Ни код, ни данные не существуют в вакууме. Данные управляют потоком кода, а код манипулирует образами и значениями данных.
Если наш код и данные являются разделенными элементами, то всегда существует опасность вызова правильной процедуры с неверными, данными или ошибочной процедуры с правильными данными. Забота о совпадении этих элементов возлагается на программиста, и хотя строгая типизация Паскаля здесь помогает, самое лучшее, что он может сделать - это указать на несоответствие.
Объект осуществляет синхронизацию кода и данных путем совместного построения их описаний. Реально, чтобы получить значение одного из полей объекта, мы вызываем относящийся к этому объекту метод, который возвращает значение нужного поля. Чтобы присвоить полю значение, мы вызываем метод, который назначает данному полю новое значение.
Однако, Borland Pascal не вынуждает нас делать это. Как всякое структурное программирование, объектно-ориентированное программирование является дисциплиной, которую мы должны навязать себе, используя предоставляемые языком средства. Borland Pascal позволяет нам обращаться к полям объекта непосредственно извне объекта, однако он поощряет нас использовать преимущества объектно-ориентированного программирования и создавать методы для манипулирования полями объекта внутри самого объекта.
Итак, подведем некоторый итог. Что такое объект?
Объект состоит из структуры данных и связанных с ней процедур (которые называются методами), которые работают с данными, записанными в экземплярах структуры данных.
Объект может наследовать характеристики порождающего объекта. Это означает, что структура данных нового объекта включает структуру данных порождающего объекта, а также новые данные. Кроме того, новый объект может вызывать все процедуры порождающего объекта, а также те процедуры методов, которые в нем описываются.
Объект, не имеющий наследования, называется базовым объектом. Объект, наследующий характеристики других объектов, называется порожденным или производным объектом.
Полиморфизм означает, что один и тот же метод выполняется по-разному для различных объектов. Например, метод класса Музыкальный инструмент – Play Music For An Orchestra (играй музыку для оркестра) - может быть определен как общий метод, который может использоваться с любой категорией музыкальных инструментов. Этот метод написан таким образом, что не важно, какой именно инструмент получает задание играть, однако для классов, описывающих конкретные инструменты, данный метод должен быть переопределен (override), что даст возможность определить конкретные действия, учитывающие особенности данного инструмента.
В класс объединяются объекты с одинаковыми свойствами и методами.
Одним из первых действий, предпринимаемых человеком при попытке понять окружающий мир, является применение к нему некоторой структурной формы. При встрече с неизвестным объектом мы пытаемся втиснуть его в нашу существующую структуру: другими словами, классифицировать его. Большинство людей знакомо по крайней мере с несколькими классификационными структурами или иерархиями.
Использование иерархии классов вводит необходимость абстракции. Классы становятся более абстрактными по мере продвижения вверх по иерархии.
Объектно-ориентированные языки используют такой же подход. Иерархии обычно начинаются с нескольких абстрактных классов. Каждый новый класс представляется как подкласс существующего класса (называемого его суперклассом). Он наследует данные и методы от классов, стоящих выше в иерархии. Только те данные и методы, которые являются новыми для этого класса, следует определить и реализовать.
Класс - это абстрактное понятие, сравнимое с понятием категория в его обычном смысле.
По определенным свойствам любого элемента определенной категории можно установить, что он принадлежит к этой категории. Сама категория определяется общими свойствами, которые имеют все экземпляры этой категории.
Это можно пояснить на примере музыкальных инструментов. Музыкальные инструменты делятся на следующие категории: духовые, ударные и струнные.
Все эти категории принадлежат к категории музыкальных инструментов. В свою очередь, категория музыкальных инструментов входит в категорию инструментов.
Музыкальные инструменты имеют общие свойства, но каждый инструмент сам по себе обладает особыми свойствами, которые определяют его назначение и отличают его от других инструментов. По тому же принципу можно описать и классы в ООП. Определенный музыкальный инструмент некоторой категории, например, труба, является объектом. Категория, к которой этот инструмент принадлежит, - это класс.
Класс в объектно-ориентированном программировании - это абстрактный тип данных, который включает не только данные, но и функции и процедуры.
Функции и процедуры класса называются методами и содержат исходный код, предназначенный для обработки внутренних данных объекта данного класса.
Наличие в классах абстрагирования, которое максимально удобно для программистов, работающих с этими классами, имеет первостепенное значение при разработке повторно используемого ПО. Если вы выстроите интерфейс, на который не влияют изменения в реализации, то вашему приложению долгое время не понадобятся никакие модификации. Если вы знакомы с предметной областью задачи, вы без труда определите, какие методы понадобятся пользователям класса. Скажем так: если при проектировании класса вам удается сочетать хорошее знание предметной области с прогнозом относительно дальнейших перспектив использования класса, можно гарантировать, что большая часть интерфейса этого класса останется неизменной, даже в случае возможного совершенствования реализации класса.
В результате отстранения пользователя от деталей реализации система в целом становится понятнее, а значит, и удобнее в работе.
Между классами также могут быть установлены отношения:
- отношение разновидности (кошка - вид определенного биологического семейства или кошка - домашнее животное);
- включения или составной части (лапа - часть кошки);
- ассоциативности, когда между классами есть чисто смысловая связь (кошки и собаки - домашние животные).
Некоторые примеры в языках:
Delphi:
TMyClass = class(TObject)
private
{Описанные в этой секции элементы не доступны извне (за пределами класса, но доступны в пределах модуля).}
{Здесь обычно находятся поля класса.}
strict private
{Для версии Delphi 2007 и выше. Описанные в этой секции элементы доступны только внутри класса}
protected
{Описанные в этой секции элементы доступны только классу и всем его потомкам.}
public
{Описанные в этой секции элементы доступны всем.}
published
{Описанные в этой секции элементы доступны всем и отображаются в Object Inspector'e.}
end;
C++:
class MyClass: public ParentClass // ParentClass — класс-предок, если таковой имеется
{
public:
// элементы в этой секции доступны из любой части программы
MyClass(); // конструктор
~MyClass(); // деструктор
protected:
// элементы в этой секции доступны из класса и его потомков
private:
// элементы в этой секции доступны только из класса; это область доступа по умолчанию
};
Ruby:
class MyClass
def initialize
# Конструктор (необязателен)
end
public # Идентификатор public необязателен, т.к. установлен по умолчанию,
# указывает на то, что следующие за ним методы доступны из любого места программы
def public_method
# Публичный метод
end
protected # Идентификатор protected указывает на то, что следующие за ним методы
# будут доступны только членам данного и дочерних классов
def protected_method
# Защищённый метод
end
private # Идентификатор private указывает на то, что следующие за ним методы
# будут доступны только членам данного класса
def private_method
# Приватный метод
end
5. Процесс объектно-ориентированного проектирования
Объектно-ориентированное проектирование (Object-Oriented Design - OOD) - это поступательный итеративный процесс. Граница между объектно-ориентированным анализом и проектированием расплывчата и построение проекта программного изделия состоит из ряда циклов, в которых уточняются описания классов и взаимодействия между ними, разрабатываются реализующие их программы, проводится их отладка и тестирование и по результатам каждого этапа уточняются рабочие документы предыдущих этапов, дорабатываются описания классов и программы. Эти циклы повторяются до получения требуемого результата.
В рассмотренном выше примере были выделены классы “множество данных” и “данное”. Пусть классу “множество данных” присвоено имя TXSet.
С учетом имеющихся инструментальных средств класс TXSet может быть построен на основе класса Array из библиотеки CLASSLIB, т.е. это множество может быть интерпретировано массивом. Массив представляет собой упорядоченную совокупность однотипных элементов, в то же время данные могут принадлежать различным типам и каждому тип соответствует свой набор характеристик. Это противоречие можно преодолеть, если элементами массива TXSet будут указатели на экземпляры данных.
Чтобы использовать указатели на экземпляры данных как элементы массива, все классы, определяющие типы данных, должны быть образованы из общего базового класса.
Пусть требуется обеспечить возможность использования числовых скалярных данных и массивов (векторов и прямоугольных матриц), а также данных типа строк и массива строк. Естественно определить для каждого такого типа свой класс: TDScal, TDArray, TDString, TDStringArray. В каждом из этих классов должно быть поле идентификатора, данного ident, поле описания, данного head и, возможно, поле flags, представляющее собой набор битов, дополняющих описание данного. Может оказаться удобным иметь и поля, содержащие количество знаков при представлении скаляра или элементов массивов (width) и количество цифр в дробной части для представления чисел (dec). Все эти данные можно объединить в классе TData, базовом для остальных классов, данных. Таким образом, вместо одного класса “данное”, выделенного на этапе анализа, появилось пять классов. После этого следует вернуться к этапу анализа и оформить рабочие документы анализа для новых классов.
Аналогичным образом следует уточнить состав и определения остальных классов, выбранных на этапе анализа.
После определение перечня классов следует разработать семантику каждого класса - определить состав и назначение методов класса. При этом также может возникнуть необходимость выделения новых классов и, следовательно, повторение отдельных частей этапа анализа и новое уточнение ранее описанных классов.
Таким образом, процесс объектно-ориентированного проектирования состоит из циклического выполнения четырех основных шагов:
- Определение классов и объектов на определенном уровне абстракции.
- Определение семантики классов.
- Определение (идентификация) связей между классами и объектами.
- Реализация классов.
На каждом повторении этого цикла уточняются описания классов и перерабатываются проектные документы.