Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прикладное программирование.doc
Скачиваний:
12
Добавлен:
25.12.2018
Размер:
683.01 Кб
Скачать

ЭЛЕКТРОСТАЛЬСКИЙ ПОЛИТЕХНИЧЕСКИЙ ИНСТИТУТ (филиал) Федерального государственного образовательного учреждения высшего профессионального образования «Государственный технологический университет «Московский институт стали и сплавов»

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

Часть 1 классы и объекты

УЧЕБНОЕ ПОСОБИЕ по курсу

"Прикладное программирование"

Введение

Object-Oriented Programming (Объектно-ориентированное программиро­вание - ООП) стало естественным способом разработки сложного программ­ного обеспечения с графическим интерфейсом пользователя. Оно основано на объектно-ориентированной модели, для которой объекты являются основ­ным предметом рассмотрения. Эта модель включает описание объектов и средства их взаимодействия друг с другом. Объектно-ориентированный под­ход при разработке программного обеспечения уже продемонстрировал свои возможности в создании систем в самых разных областях любого размера и сложности.

Объект (Object) - это переменная структурированного типа данных, включающая, как элементы данных, так и операции с этими элементами, упакованными вместе для удобства использования. Объединение данных и кода в одну конструкцию называется инкапсуляцией (encapsulation). Важно подчеркнуть, что операции и данные, которыми они оперируют, тесно связа­ны друг с другом. Простое включение операций и данных в одну структуру возможно и в паскалевской записи.

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

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

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

При определенных обстоятельствах объекты могут вызывать методы-операции не только их непосредственного класса, но и любого из классов-предков, таким образом поддерживается полиморфизм (polymorphism). По­лиморфизм - это, в переводе с греческого, много форм. Применительно к ООП это означает, что может существовать несколько версий какого-то ме­тода и один и тот же вызов этого метода может использовать различные его версии.

1. Классы и объекты

Данные в объекте определяются и выглядят подобно полям записи (Record) в Паскале, но без вариантной части. Могут быть объявлены поля различных типов, которым при создании объекта или в процессе работы про­граммы присваиваются конкретные значения. Комбинация значений всех по­лей объекта определяет состояние этого объекта. Изменение значения поля изменяет и состояние объекта. Поэтому значения полей уникальны для каж­дого экземпляра класса (объекта), хотя и может быть несколько объектов с полностью идентичными значениями полей.

Объявляются поля данных внутри описания класса способом, аналогич­ным определению полей записей и похожим на объявление обычных пере­менных. Можно перечислить одно или более имен полей одного типа, разде­ленных запятыми, а затем указать наименование типа, отделив его двоеточи­ем. Заканчивается каждое описание точкой с запятой после названия типа.

Как источник действий, объект использует набор методов, т.е. подпро­грамм, разработанных для операций с полями. Все методы совместно опре­деляют поведение объекта. Активирование метода объекта проявляется в действии, совершаемом объектом. Адреса вызова некоторых методов объекта определяются на этапе компиляции программы, а других - с помощью специ­альной таблицы, создаваемой после инициализации программы. Каждый объект содержит указатель на такую специальную таблицу, содержащую ин­формацию, необходимую для вызова метода. Эта таблица является принад­лежностью класса и для нее выделяется память. Таким образом, методы у объектов одного класса общие.

Классическое правило ООП утверждает, что для обеспечения надежно­сти нежелателен прямой доступ к полям объекта: чтение и изменение их со­держимого должно производиться посредством вызова соответствующих ме­тодов. В объектах Delphi пользователь может быть полностью отгорожен от полей с помощью свойств, в то время как поля у записи не защищены и дос­тупны для возможного неверного использования.

Таким образом, класс - это структурированный тип данных языка Object Pascal (OP). Класс представляет собой описание того, как будет выглядеть и вести себя его представитель (экземпляр или объект).

Во многих объектно-ориентированных языках объявление переменной, имеющей тип класса, автоматически создает объект. В OP вместо этого ис­пользуется ссылочная модель объектов (object reference model), т.е. каждая переменная типа класса содержит не значение объекта, а лишь ссылку (указатель) на область памяти, в которой содержится объект, т.е. переменная типа класс - это просто ссылка на экземпляр. Таким образом, в OP все экзем­пляры или объекты могут быть только динамическими, поэтому отпала необ­ходимость в использовании непременного атрибута указателя '^' - caret.

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

Отметим, что, объявляя в программе переменную того или иного класса, мы фактически при работе программы лишь создадим структуру, включаю­щую только поля, а методы у всех экземпляров одного класса размещены в одном месте - в описании класса. Доступ к ним осуществляется через указа­тель на класс, имеющийся у каждого экземпляра.

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

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

а) Объявление класса, т.е. объявление типа данных, определяет состав полей данных экземпляров класса и набор допустимых операций над ними, и его синтаксис следующий:

Type <имя класса>=Сlass[(<имя родительского класса>)}

Определение класса> // Определение полей, свойств и методов

End;

Примечания:

Классы могут быть объявлены либо в секции интерфейса модуля, либо на верхнем уровне вложенности секции реализации. Таким образом, не до­пускается описание класса внутри процедур и функций и других блоков кода. Они могут быть только глобальными типами.

Возможно предварительное объявление класса, но без использования директивы Forward'.

Type <имя класса>=Сlass[(<имя родительского класса>)};

В OP у всех классов есть общий класс-прародитель TObject. При создании пользовательского класса непосредственно от TObject имя родитель­ского класса можно не указывать.

Определение класса может быть разделено на несколько разделов с разной степенью видимости (доступности) их компонентов. Каждый раздел может начинаться с одного из ключевых слов-директив: Private, Protected, Public, Published (если компилировался с директивой SM+). По умолчанию, если нет ни одного слова-директивы или до первой ди­рективы. определяющим разделом является Public.

Объявление класса включает три основных группы компонентов объ­ектов, называемых интерфейсом класса:

данные объекта или атрибуты исходных данных, называемые чаще всего полями;

' методы объекта или операции над данными;

свойства объекта - это высокоуровневые атрибуты данных, которые тесно свя­заны с соответствующими методами доступа к данным.

Объявление полей в каждом из четырех разделов объявления класса должно предшествовать объявлению методов и свойств.

Имена классов принято начинать с буквы Т, а имена полей с буквы F.

По существу имеется два вида полей внутри экземпляра класса: поля прямого доступа и косвенного доступа:

поле прямого доступа - это реальная часть данных, непосредственно встроен­ная в экземпляр класса. Примером может служить целое число или строка. Прямой дос­туп требует ресурса памяти для хранения каждого экземпляра класса, в точности рав­ного объявленному размеру, поэтому значения этих полей могут храниться внутри каж­дого экземпляра класса. Выделение памяти под строки Delphi делает динамически и ав­томатически:

поле косвенного доступа - это ссылка на некоторый другой объект, обычно на экземпляр другого класса. Поле косвенного доступа требует сравнительно немного па­мяти для хранения ссылки, поскольку в этом поле хранится адрес - 4 байта.

Объект может содержать (включать) другой объект, т.е. владеть им. В этом случае объект-хозяин ответственен как за создание экземпляра этого объекта (выделение памяти соответствующим конструктором, ко­гда это необходимо), так и за уничтожение (соответствующим деструк­тором, когда он больше не требуется). Например, экранная форма владеет всеми объектами, на ней расположенными: кнопками, полями редактирова­ния и т.п.

Объект может быть ассоциирован с другим объектом. В этом слу­чае объекты "знают " друг о друге, могут вызывать методы друг друга и ссылаться, но они не отвечают за создание и уничтожение друг друга. На­пример, совокупность компонентов для работы с базами данных, организа­ции DDE-связи и т.п.

б) Создание экземпляра класса. Для создания экземпляра необходимо объявить переменную в секции Var, а затем отвести ей память в куче соот­ветствующим конструктором.

в) Обращение к полям экземпляра класса. Можно обращаться к полям данных следующим образом:

• используя точечную нотацию (или полное имя):

<имя объекта>.<имя поля>:=<значение>;

• используя оператор With, как при обращении к полям записи в Паска­ле:

With <имя объекта> Do Begin

<имя поля ]>:=<значение1>;

<имя поля 2>:=<значение2>;

. . .

End;

Рассмотрим пример объявления, создания и использования объекта.

• Объявим класс TLine:

Type TLine=Class

X, Y, Length, Angle: Integer; // Поля класса

Constructor Create; // Конструктор класса

Procedure MoveTo(NewX, NewY: Integer); // 1-й метод класса

Procedure Rotate(ByAngle: Integer); // 2-й метод класса

End;

• Объявим и создадим экземпляр класса, выделив под него память: