Основные принципы ООП (инкапсуляция, полиморфизм, наследование).

ООП базируется на трех основных принципах: инкапсуляция, наследование, полиморфизм. Эти принципы ООП работают вместе и практически не существуют отдельно друг от друга.

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

Наследование – это возможность создания новых объектов, которые обладают свойствами и поведением родительских объектов.

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

 

Реализация ООП в Delphi (объявление и реализация классов, поля, методы и свойства, создание и уничтожение экземпляров классов, конструкторы и деструкторы).

 

Реализация ООП в Delphi (объявление и реализация классов, поля, методы и свойства, создание и уничтожение экземпляров объектов, конструкторы и деструкторы).

 

Инкапсуляция

Для описания объектов служат классы. Каждый объект является экземпляром какого-либо класса.

ООП реализуется в Delphi с использованием типа class,который представляет собой особую структуру, содержащую в своем составе поля, методы и свойства. Ниже приведен пример класса.

Type

TInfo = class

FKey: Integer; // поле

procedureShow; // метод1

functionGetKey: Integer; // метод2

constructorCreate; // конструктор

destructorDestroy; // деструктор

end;

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

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

Чтобы использовать новый тип в программе, нужно объявить переменную этого типа.

Переменная объектного типа называется экземпляром класса или объектом:

Var

AMyObject: TInfo; // одна переменная

A: array[1..10] ofTInfo; // массив переменных

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

Для работы с переменной объектного типа недостаточно только ее описания. Инициализация переменной производится специальным методом, называемым конструктором:

AMyObject := TInfo.Create;

Конструктор – это функция, возвращающая созданный и проинициализированный объект. В конструкторе обычно присваиваются значения всем полям метода.

constructorTInfo.Create;

Begin

Fkey := -1;

end;

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

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

Объект уничтожается, когда вызывается метод destructor. Ему дают имя Destroy (никто еще по-другому не называл, хотя можно). Деструктор переопределяют, если при создании объекта выделялась динамическая память. Для нашего простого класса деструктор можно не добавлять, а использовать унаследованный от TObject.

Необходимо взять за правило – всегда уничтожать и освобождать все, что было создано в программе.

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

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

Type

TMyClass = class

FKey: Integer;

...

functionGetKey: Integer;

procedureSetKey(constValue: Integer);

propertyKey: Integer readGetKey writeSetKey;

...

end;

Соответствующие реализации:

functionTMyClass.GetKey: Integer;

Begin

Result := FKey;

end;

procedureTMyClass.SetKey(constValue: Integer);

Begin

ifFkey <> ANewKey then

Begin

Fkey := ANewKey;

... // здесь могут выполняться дополнительные действия

end;

end;

В методах, входящих в состав свойств может осуществляться проверка устанавливаемой величины на попадание в допустимый диапазон значений и вызов других процедур, зависящих от вносимых изменений. Если же потребности в специальных процедурах чтения и/или записи нет, можно вместо имен методов применять имена полей:

Type

TMyClass = class

FKey: Integer;

...

procedureSetKey(constValue: Integer);

propertyKey: Integer readFKey writeSetKey;

...

end;

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

Type

TMyClass = class

FKey: Integer;

...

propertyKey: Integer readFKey;

...

end;

Попытка присвоить значение свойству вызовет ошибку компиляции.