- •Объектно-ориентированный анализ
- •Объектно-ориентированное программирование.
- •Объектно-ориентированное проектирование.
- •Основные понятия объектно-ориентированного проектирования.
- •Классы и объекты в Object Pascal.
- •Важнейшие принципы объектно-ориентированного программирования.
- •Составляющие класса.
- •Объекты
- •Создание и уничтожение объектов.
- •Наследование конструкторов и деструкторов.
- •Свойства и инкапсуляция.
- •Статические методы.
- •Полиморфизм. Виртуальные и динамические методы.
- •Абстрактные методы.
- •Перекрытие виртуальных и динамических методов.
- •Как устроен объект изнутри
- •Перезагрузка методов.
- •Задача с использованием полиморфизма
- •Области видимости.
- •Создание класса комплексных чисел.
- •Создание класса векторов
- •Объект-список
- •Модуль по работе со списками
- •Основная программа по работе с объектами-списками
- •Система программирования Delphi
- •Терминология Delphi.
- •Первые шаги визуального программирования в среде Delphi.
- •Иерархия компонентов.
- •Собственники компонентов
- •Элементы управления.
- •Компоненты (tComponent)
- •Оконные не оконные
- •Родительские и дочерние компоненты.
- •Объектно-событийное программирование. События
- •Реакции на события
- •Программирование реакции на событие
- •Особенности реализации событий
- •Делегирование событий
- •Виды событий
- •Диалоги. Работа с файлами. Открытие и закрытие файлов с использованием стандартных диалоговых окон.
- •TOpenDialog и tSaveDialog – диалоги открытия и сохранения файлов (страница dialogs )
- •Компонент класса tform
- •Создание и использование форм
- •Шаблоны форм
- •Программы со многими формами
- •Модульный принцип построения программ.
- •Программные файлы. Основные типы файлов проекта. Простейшее приложение.
- •Структура головного файла проекта.
Статические методы.
По умолчанию методы класса являются статическими – их адрес определяется во время компиляции программы (раннее связывание), поэтому они вызываются быстрее всего.
В одноименных статических методах порожденных классов списки параметров могут отличаться.
Со статическим методом связан следующий способ наследования: если в описании потомка появляется метод с тем же именем, что и у предка, то в этом типе и во всех его потомках этот метод будет перекрыт (замещен, переопределен).
При обращении к статическому методу компилятор точно знает класс, которому данный метод принадлежит. Описанный тип класса (во время компиляции) или объектная переменная, используемая в вызове статического метода, определяет, которое выполнение метода активировать.
Например:
type TFigure=class
procedure draw;
end;
TRectangle=class (TFigure)
procedure draw; {эта процедура будет перекрыта
предыдущей}
end;
… … … …
var Figure:TFigure;
Rectangle:TRectangle;
begin
Figure:=TFigure.create;{конструктор create уноследова
у предка}
Figure.draw;
{вызывается метод draw класса TFigure}
Figure.free; {уничтожаем объект Figure}
Figure:=TRectangle.create; {Figure-новая, отличная от
предыдущей}
Figure.draw;
{вызывается метод draw класса TRectangle}
Figure.free;
Rectangle:=TRectangle.create; {описываем новую
переменную}
Rectangle.draw;
{вызывается метод draw класса TRectangle}
Rectangle.free;
end.
Здесь разные методы с именами draw вызываются в разных классах. Их адрес определяется при компиляции, поэтому статические методы вызываются быстрее всех.
Полиморфизм. Виртуальные и динамические методы.
Принципиально отличаются от статических виртуальные и динамические методы.
В Delphi чаще используется динамическое замещение методов на этапе прогона программы. Для реализации этого метод, замещаемый в родительском классе должен объявляться как динамический (dynamic) или виртуальный (virtual). Встретив такое объявление компилятор создает две таблицы:
DMT – Dynamic Method Table
VMT – Virtual Method Table
Далее компилятор поместит в них адреса точек входа соответственно динамических и виртуальных методов. При каждом обращении к замещаемому методу компилятор вставляет код, позволяющий извлечь адрес точки входа в подпрограмму из той или другой таблицы. А в классе – потомке замещающий метод объявляется с директивой Override (перекрыть). Получив это указание, компилятор создаст код, который при выполнении программы поместит в родительскую таблицу точку входа метода класса – потомка, что позволит родителю выполнить нужные действия с помощью нового метода.
Пример1. Пусть существует некоторый обобщенный класс для хранения данных и два его потомка для хранения строк и целых чисел:
Пример 1:
Type TField=class {класс родитель}
function GetData: string; virtual; abstract;
end;
TStringField=class(TField) {класс потомок}
FData:string;{поле}
Function GetData: string; override;{метод
перекрыт}
end;
TIntegerField=class(TField){класс потомок}
FData:integer;{поле}
function GetData: string; override;{перекрыт}
end;
. . . . .
function TStringField.GetData;{описывается метод
GetData класса TStringField}
begin
Result:=FData;
end;
function TIntegerField.GetData; {описывается
метод GetData класса TIntegerField}
begin
Result:=IntToStr(FData);
end;
. . . . .
Procedure Show (F:TField);
begin
Form1.Label1.Caption:= F.GetData;
end;
. . . . .
В этой задаче классы TIntegerField и TStringField содержат разнотипные поля данных FData и единственное что они умеют – это сообщать о значении своих данных текстовой строкой при помощи метода GetData
В каждом классе сообщается о значении разнотипных полей. Внешняя процедура Show получает объект в виде параметра и показывает строку данных. (Form1.Label1.Caption:= F.GetData;) В процедуре Show параметр F описан как объект класса TField. Это значит, что в нее можно передавать объекты классов TStringField, TIntegerField как потомков класса TField.
Возникает вопрос: чей метод GetData при этом будет вызван? Ответ: тот, который соответствует классу фактически переданного объекта.
Т.о. правило соответствия типов языка Object Pascal гласит: объекту, как указателю на экземпляр объектного типа может быть присвоен адрес любого экземпляра любого из дочерних типов. Этот принцип называется полиморфизмом. Полиморфизм – наиболее важный принцип ООП.
В нашем примере программисту, пишущему процедуру Show важно лишь, что любой объект, переданный в нее, является потомком класса TField.
Если такую процедуру скомпилировать и поместить в динамическую библиотеку, то эту библиотеку можно будет раз и навсегда использовать без изменений, хотя будут появляться и новые, неизвестные в момент её создания классы-потомки TField.