Инкапсуляция и свойства объекта
Под инкапсуляцией понимается скрытие полей объекта с целью обеспечения доступа к ним только посредством методов класса.
В языке Delphi ограничение доступа к полям объекта реализуется при помощи свойств объекта. Свойство объекта характеризуется полем, сохраняющим значение свойства, и двумя методами, обеспечивающими доступ к полю свойства. Метод установки значения свойства называется методом записи свойства (write), а метод получения значения свойства – методом чтения свойства (read).
В описании класса перед именем свойства записывают слово property (свойство). После имени свойства указывается его тип, затем – имена методов, обеспечивающих доступ к значению свойства. После слова read указывается имя метода, обеспечивающего чтение свойства, после слова write – имя метода, отвечающего за запись свойства.
Ниже приведен пример описания класса TPerson, содержащего два свойства: Name и Address.
type TName = string [15]; TAddress = string[35]; TPerson = class // класс private FName: TName; // значение свойства Name FAddress: TAddress; // значение свойства Address Constructor Create(Name:Tname); Procedure Show; Function GetName: TName; Function GetAddress: TAddress; Procedure SetAddress(NewAddress:TAddress); public Property Name: Tname // свойство Name read GetName; // доступно только для чтения Property Address: TAddress // свойство Address read GetAddress // доступно для чтения write SetAddress; // и записи end;
В программе для установки значения свойства не нужно записывать инструкцию применения к объекту метода установки значения свойства, а надо записать обычную инструкцию присваивания значения свойству. Например, чтобы присвоить значение свойству Address объекта student, достаточно записать:
student.Address: = 'С.Петербург, ул.Садовая 21, кв.3';
Компилятор перетранслирует приведенную инструкцию присваивания значения свойству в инструкцию вызова метода:
student.SetAddress('С.Петербург, ул.Садовая 21, кв.3');
Внешне применение свойств в программе ничем не отличается от использования полей объекта. Однако между свойством и полем объекта существует принципиальное отличие: при присвоении и чтении значения свойства автоматически вызывается процедура, которая выполняет некоторую работу.
В программе на методы свойства можно возложить некоторые дополнительные задачи. Например, с помощью метода можно проверить корректность присваиваемых свойству значений, установить значения других полей, логически связанных со свойством, вызвать вспомогательную процедуру.
Оформление данных объекта как свойства позволяет ограничить доступ к полям, хранящим значения свойств объекта: например, можно разрешить только чтение. Для того чтобы инструкции программы не могли изменить значение свойства, в описании свойства надо указать лишь имя метода чтения. Попытка присвоить значение свойству, предназначенному только для чтения, вызывает ошибку времени компиляции. В приведенном выше описании класса TPerson свойство Name доступно только для чтения, а свойство Address – для чтения и записи.
Установить значение свойства, защищенного от записи, можно во время инициализации объекта. Ниже приведены методы класса TPerson, обеспечивающие создание объекта класса TPerson и доступ к его свойствам.
// конструктор объекта TPerson Constructor TPerson.Create(Name:TName); begin FName: = Name; end; // метод получения значения свойства Name Function TPerson.GetName; begin Result: = FName; end; // метод получения значения свойства Address function TPerson.GetAddress; begin Result: = FAddress; end; // метод изменения значения свойства Address Procedure TPerson.SetAddress(NewAddress:TAddress); begin if FAddress =' ' then FAddress: = NewAddress; end;
Приведенный конструктор объекта TPerson создает объект и устанавливает значение поля FName, определяющего значение свойства Name.
Инструкции программы, обеспечивающие создание объекта класса TPerson и установку его свойства, могут быть, например, такими:
student: = TPerson.Create('Иванов'); student.Address: = 'ул. Садовая, д.3, кв.25';