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


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

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



Объе́ктно-ориенти́рованное или объектное программи́рование (в дальнейшем ООП) — парадигма программирования, в которой основными концепциями являются понятия объектов и классов (либо, в менее известном варианте языков с прототипированием, — прототипов).

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

В Delphi типы объектов называются классами, а сами объекты являются ди­намическими переменными (символ «^» не используется).

Наследственность и полиморфизм

Свойство наследственности заключается в том, что любой класс может быть порожден от другого класса с наследованием всех свойств. Если класс В порожден от класса А, то класс А называют - «класс-родитель», а В - «класс-потомок». Порожденный класс автоматически наследует поля и методы своего родителя. Прародителем всех классов в Delphi является класс TObject.

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

Создание, уничтожение и операция присваивания объектов

Как всякая динамическая переменная, объект перед началом работы с ним должен быть создан. Нужно выделить под него динамическую область памяти и инициализировать (т.е. подготовить к работе) созданный объект. Для этого в Delphi служит конструктор Create, который является методом класса TObject. Применяется конструктор следующим образом:

<Имя-переменной-типа-класс>:= <тип-класса>. Create;

После окончания работы с объектом выделенную под него память необходи­мо освободить, для чего служат деструкторы класса TObject Destroy или Free. Метод Free удобнее использовать, так как он в отличие от метода Destroy перед освобождением памяти проверяет, не была ли она уже освобождена ранее, т.е. работает более корректно:

<Имя-переменной-типа-класс>. Free;

При необходимости в состав любого пользовательского класса могут быть введены свои методы Constructor и Destructor, которые дополняют Create и Free новыми функциями.

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

Статический, виртуальный и динамический способы реализации полиморфизма

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

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

Статические методы характеризуются тем, что связывание метода с полями осуществляется во время компиляции (раннее связывание).

Виртуальные и динамические методы связываются во время выполнения программы (позднее связывание). Если метод объявлен виртуальным или ди­намическим, то нельзя менять типы и число параметров.

Для реализации позднего связывания поступают следующим образом.

В потомке замещающий метод объявляется директивой override. Замещаемый од­ноименный метод родителя объявляется как динамический или виртуальный с помощью ключевых слов {dynamic) или {virtual). Вызов перекрытого метода родительского класса в одноименном методе потомка достигается с помощью зарезервированного слова Inherited (унаследованный).

Встретив объявления dynamic или virtual, компилятор создает таблицы соот­ветствия DMT и VMT. В этих таблицах помещаются адреса точек входа мето­дов. Адрес VMT «своего» класса хранится в каждом экземпляре объекта в осо­бом, скрытом от программиста поле. Адрес DMT хранится в VMT. При каждом обращении к методу компилятор вставляет в соответствующую таблицу код, позволяющий извлечь затем из нее адрес точки входа в подпрограмму.

Отличие таблиц DMT и VMT в том, что DMT содержит адреса только тех методов, которые объявлены как dynamic в данном классе, a VMT содержит ад­реса всех виртуальных методов данного класса: как нововведенных, так и унаследованных от родителей.

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

Правила ООП требуют, чтобы обращение к полям осуществлялось посредст­вом методов, однако это не всегда удобно. Поэтому класс имеет свойства - специальный механизм, регулирующий доступ к полям. Свойства объявляют­ся с помощью специальной конструкции property..., read..., write

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

Концепции

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

Необходимость совместного использования объектов разных классов, способных обрабатывать однотипные сообщения, требует поддержки полиморфизма — возможности записывать разные объекты в переменные одного и того же типа. В таких условиях объект, отправляя сообщение, может не знать в точности, к какому классу относится адресат, и одни и те же сообщения, отправленные переменным одного типа, содержащим объекты разных классов, вызовут различную реакцию.

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

Однако общность механизма обмена сообщениями имеет и другую сторону — «полноценная» передача сообщений требует дополнительных накладных расходов, что не всегда приемлемо. Поэтому в большинстве ныне существующих объектно-ориентированных языков программирования используется концепция «отправка сообщения как вызов метода» — объекты имеют доступные извне методы, вызовами которых и обеспечивается взаимодействие объектов. Данный подход реализован в огромном количестве языков программирования, в том числе C++, Object Pascal, Java, Oberon-2. В настоящий момент именно он является наиболее распространённым в объектно-ориентированных языках.

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



Поделиться:


Последнее изменение этой страницы: 2016-08-15; просмотров: 458; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.191.195.110 (0.006 с.)