Инкапсуляция и свойства объекта
Под инкапсуляцией понимается скрытие полей объекта с целью обеспечения доступа к ним только посредством методов класса.
В Object Pascal ограничение доступа к полям объекта реализуется с помощью свойств объекта. Свойство объекта характеризуется полем, хранящим значение свойства, и двумя методами, обеспечивающими доступ к полю свойства. Метод установки значения свойства называется методом записи свойства (write), метод получения значения свойства называется методом чтения свойства (read).
В описании класса перед именем свойства записывают ключевое слово property (свойство). После имени свойства указываются его тип, затем имена методов, обеспечивающих доступ к значению свойства. После слова read указывается имя метода, обеспечивающего чтение свойства, после слова write —имя метода, обеспечивающего запись свойства. Ниже приведен пример описания класса TTPerson, содержащего два свойства: Name и Address.
Type
TName=string[15];
TAddress=string[35];
TTPerson = class
Private
FName:Tname; //значение свойства Name
FAddress:TAddress; // значение свойства Address
Constructor Create(Name:Tname);
ProcedureShow;
Function GetName:TName;
Function GetAddress:TAddress;
Procedure SetAddress(NewAddress:TAddress);
Public
Property Name: Tname
read GetName;
Property Address: TAddress
read GetAddress;
write SetAddress;
end;
В программе для установки значения свойства необязательно записывать оператор применения к объекту метода установки значения свойства, можно записать обычный оператор присваивания значения свойству. Например, чтобы присвоить значение свойству Address объекта student, достаточно записать
|
|
student.Address:=’С.Петербург, ул. Садовая, 21, кв.3’;
Компилятор перетранслирует приведенный оператор присваивания значения свойству в оператор вызова метода:
student.SetAddress('С.Петербург, ул. Садовая, 21, кв.3');
Внешне использование свойств в программе ничем не отличается от использования полей объекта. Вместе с тем между свойством и полем объекта существует принципиальное отличие: при присвоении и чтении значения свойства автоматически вызывается процедура, которая выполняет некоторую работу.
В программе на методы свойства можно возложить некоторые дополнительные задачи. Например, с помощью метода можно проверить корректность присваиваемых свойству значений, установить значения других, логически связанных со свойством, полей, вызвать вспомогательную процедуру.
Оформление данных объекта как свойства позволяет ограничить доступ к полям, хранящим значения свойств объекта, например можно разрешить только чтение. Чтобы операторы программы не могли изменить значение свойства, в описании свойства надо указать только имя метода чтения. Попытка присвоить значение свойству, предназначенному только для чтения, вызывает ошибку времени компиляции В приведенном выше описании класса TTPerson свойство Name доступно только для чтения, а свойство Address — для чтения и записи.
|
|
Установить значение свойства, защищенного от записи, можно во время инициализации объекта. Ниже приведены методы класса TTPerson, обеспечивающие создание объекта класса TTPerson и доступ к его свойствам.
//конструктор объекта TTPerson
Constructor TTPerson.Create(Name:TName);
Begin
Fname:=Name;
end;
//метод получения значения свойства Name
Function TTPerson.GetName;
Begin
Result:=FName;
end;
//метод получения значения свойства Address
Function TTPerson.GetAddress;
Begin
Result:=FAddress;
end;
//метод изменения значения свойства Address
Procedure TTPerson.SetAddress(NewAddress:TAddress);
Begin
if FAddress =’’
then FAddress:=NewAddress;
end;
Приведенный конструктор объекта TTPerson создает объект и устанавливает значение поля FName, определяющего значение свойства Name.
Операторы программы, обеспечивающие создание объекта класса TTPerson и установку его свойства, могут быть, например, такими:
student:=TTPerson.create('Иванов');
student.address:=’ул. Садовая, д.21, кв. 3’;
Наследование
Концепция объектно-ориентированного программирования предполагает возможность определять новые классы посредством добавления полей, свойств и методов к уже существующим классам. Такой механизм получения новых классов называется порождением. При этом новый, порожденный, класс (класс-потомок) наследует свойства и методы своего базового, родительского класса.
|
|
В объявлении класса-потомка указывается класс родителя. Например, класс TEmployee (сотрудник) может быть порожден от рассмотренного выше класса TTPerson путем добавления поля Department (отдел). Объявление класса TEmployee в этом случае может выглядеть так:
TEmployee = class(TTPerson)
FDepartment:integer; // номер отдела
constructor Create(Name:TName;Dep:integer);
end;
Заключенное в скобки имя класса TTPerson показывает, что класс TEmployee является производным от класса TTPerson. В свою очередь, класс TTPerson является базовым для класса TEmployee.
Класс TEmployee имеет свой собственный конструктор, который обеспечивает инициализацию класса родителя и своих полей. Пример реализации конструктора класса TEmployee:
constructor TEmployee.Create(Name:Tname;Dep:integer);
Begin
inherited Create(Name);
FDepartment:=Dep;
end;
В приведенном примере директивой inherited вызывается конструктор родительского класса, затем присваивается значение полю класса потомка.
После создания объекта производного класса в программе можно использо-. вать поля и методы родительского класса. Ниже приведен фрагмент программы, демонстрирующей эту возможность:
|
|
engineer:=TEmployee.create('Сидоров',413);
engineer.address:='ул.Блохина, д.8, кв.10';
Первый оператор создает объект типа TEmployee. Второй устанавливает значение свойства, которое относится к родительскому классу.
Области видимости в классах
Как отмечалось в п. 2.1, помимо объявлений элементов класса (полей, методов, свойств) описание класса, как правило, содержит несколько директив, которые устанавливают степень видимости элементов класса в программе.
Рассмотрим семантику директив видимости.
1. Директива private.
Поля, свойства и методы, описанные в разделе private,называются личными или закрытыми. Сюда помещаются элементы (чаще всего поля), которые выполняют в объекте специфичные функции и которые поэтому целесообразно скрыть от других частей программы, либо такие элементы, для которых по ряду причин не следует разрешать доступ извне объекта.
2. Директива public.
Элементы, описанные в разделе public, называются общедоступными. Они могут быть использованы всюду в программе. Поля, свойства и методы, расположенные сразу после заголовка класса, при выключенной директиве компилятора {$M-}, по умолчанию принимаются общедоступными.
3. Директива protected.
Элементы класса, объявленные в разделе protected(защищенный), доступны только в классах, порожденных от исходного. Здесь размещаются элементы, которые важны лишь для функционирования объектов данного класса и его потомков. Обычно в секцию protected помещаются описания методов класса.
4. Директива published.
Поля, свойства и методы, описанные в разделе published, называются опубликованными. Их область видимости эквивалентна области видимости общедоступных описаний. Отличие состоит в том, что информация о них, за исключением ряда типов, например real, на этапе проектирования программы помещается в инспектор объектов. Описания, расположенные сразу после заголовка класса, при включенной директиве компилятора {$M+}, по умолчанию принимаются опубликованными.
5. Директива automated.
Элементы класса, объявленные в разделе automated, называются автоматическими. Их область видимости эквивалентна области видимости общедоступных описаний. Отличие состоит в том, что для автоматических свойств и методов генерируется дополнительная информация, которая используется для реализации OLE-механизма. Использовать директиву automatedимеет смысл при объявлении потомков стандартного класса TAutoObject.
Ниже приведено описание класса TTPerson, в которое включены директивы видимости.
ТТРегsоп = class
Private
FName:TName; { значение свойства Name }
FAddress:TAddress; ( значение свойства Address}
Protected
Constructor Create(Name:TName);
Function GetName:TName;
Function GetAddress:TAddress;
Procedure SetAddress (NewAddress: TAddress);
Property Name:TName
read GetName;
Property Address:TAddress
read GetAddress
write SetAddress;
end;
Примечание.
Если необходимо, чтобы элементы класса были скрыты полностью, определение класса следует поместить в отдельный модуль.
Дата добавления: 2018-04-15; просмотров: 391; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!