Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Для разграничения доступа к свойствам и методам экземпляров классов между различными частями программы предусмотрены модификаторы доступа («видимости»), приведенные в табл. 3.1.
Модификатор доступа в Delphi (как и в Pascal, но в отличие от некоторых других языков программирования) относится не к конкретному свойству или методу класса, а ко всем элементам класса (свойствам и методам), описание которых располагается после указания модификатора.
Один и тот же модификатор может указываться в описании класса более одного раза.
Сравнительная таблица модификаторов доступа в Pascal и Delphi Таблица 3.1
Модификатор | Область видимости свойства или метода, помеченного модификатором | ||
Pascal | Delphi | ||
Private | описание класса и модуль, в котором описан класс, в том числе и для других классов | Так же | |
Protected | не используется | как у private + в классах, унаследованных от этого класса | |
Public | любая часть программы | так же | |
Published | не используется | как у public + в Инспекторе объектов Delphi для визуального построения программ |
Стандартное описание класса содержит свойства и методы, расположенные в порядке возрастания их видимости, но это правило не является обязательным.
Туре
<Имя класса> = class
Private {Описание свойств класса, имеющих область видимости private}
<Имя свойства 1>: <Тип свойства 1>;
…
<Имя свойства N>: <Тип свойства N>;
<Заголовок метода 1>; {Описание методов класса, имеющих область
… видимости private}
<Заголовок метода M>;
Protected {Описание свойств класса, имеющих область видимости protected}
<Имя свойства 1>: <Тип свойства 1>;
…
<Имя свойства N>: <Тип свойства N>;
<3аголовок метода 1>; {Описание методов класса, имеющих
… область видимости protected}
<Заголовок метода M>
public
<Имя свойства 1>: <Тип свойства 1>; {Описание свойств класса,
… имеющих область видимости public}
<Имя свойства N>: <Тип свойства N>;
<Заголовок метода 1>; {Описание методов класса, имеющих
… область видимости public}
<Заголовок метода М>;
Published {Описание специальных свойств класса (property), имеющих
область видимости published}
End;
Различные области видимости свойств и методов объекта предназначены для упрощения поддержания целостности информации в объектах.
Рассмотрим класс, в котором содержатся три свойства — а, b и с, причем с является произведением а и b. Если свойства а, b и с будут иметь широкую область видимости public, то есть будут доступны из любого фрагмента основной программы, то объект — экземпляр такого класса может содержать некорректные данные, так как существует возможность изменения свойств а и b без пересчета свойства с. Для выхода из такой ситуации можно предложить два подхода, и оба они связаны с использованием областей видимости свойств объекта.
Первый подход (см. листинг 3.5) состоит в том, чтобы скрыть свойства а и b от вызывающих подпрограмм, назначив им узкие области видимости, например private или protected. Выбор того или иного модификатора определяется необходимостью использования скрываемых свойств в классах-потомках данного класса. Если такой необходимости нет, то назначается область видимости private, если объекты-потомки должны иметь прямой доступ к свойствам, то назначается область видимости protected.
В любом случае, внешние подпрограммы не смогут обратиться к свойствам а и b, поэтому придется предусмотреть методы, которые их устанавливают. В этих методах, помимо установки значений свойств, должен производиться пересчет свойства с. Это будет гарантировать целостность данных объекта при изменении свойств а и b.
Заметим, что методы установки должны иметь широкую область видимости, чтобы к ним можно было обратиться из любого места программы.
Листинг 3.5. Задание областей видимости. Первый подход
Unit UsingPrivatel; {Заголовок модуля}
Interface {Начало интерфейсной части}
Туре
ABC = class {Заголовок класса ABC}
private {Начало области видимости private}
a, b: Double; {Свойства а и b имеют узкую область видимости}
public {Начало области видимости public}.
с: Double; {Свойство с имеет широкую область видимости}
Procedure SetA(NewA: Double);
{Метод SetA имеет широкую область видимости}
Procedure SetB(NewB: Double);
{Метод SetB имеет широкую область видимости}
end;
Implementation {Начало описательной части}
Procedure ABC.SetA(NewA: Double);
{Описание метода. SetA класса ABC}
Begin
a:= NewA; {Установка значения свойства а}
с:= a * b; {Обновление значения свойства с — поддержание
целостности данных}
end;
Procedure ABC.SetB(NewB: Double);
{Описание метода SetB класса ABC}
Begin
b:= NewB; {Установка значения свойства b}
с:= a * b; {Обновление значения свойства с — поддержание
целостности данных}
end;
end. {Окончание модуля}
При такой конструкции класса вызывающая подпрограмма не сможет изменить значения свойств а и b, не повлияв тем самым на значение свойства с, поэтому целостность данных не будет нарушена. Однако свойство с доступно для изменения, даже если его значение пересчитано при установке значений а и b. В итоге оно может измениться, вызвав несоответствие данных. Таким образом, лучше было бы скрыть свойство с, реализовав специальный метод доступа к его значению (листинг 3.6).
Листинг 3.6. Задание областей видимости. Второй подход
Unit UsingPrivate2; {Заголовок модуля}
Interface {Начало интерфейсной части}
Туре
АВС2 = class {Заголовок класса ABC2}
Private {Начало области видимости private}
с: Double; {Свойство с имеет узкую область видимости}
Public {Начало области видимости public}
a, b: Double; {Свойства а и b имеют широкую область видимости}
Function GetC: Double;
{Метод GetC имеет широкую область видимости}
end;
Implementation {Начало описательной части}
Function ABC2.GetC: Double;
{Описание метода GetC класса АВС2}
Begin
с:= а * b; {Обновляем значение свойства с}
Result:= с; {Возвращаем значение с вызывающей подпрограмме}
end;
end. {Окончание модуля}.
При такой конструкции класса целостность данных не может быть нарушена вызывающими подпрограммами, если только они не находятся в одном модуле с описываемым классом, то есть, в данном случае, в модуле UsingPrivate2. Единственным недостатком такого подхода является постоянный пересчет значения с при каждом обращении к методу GetC. Поэтому наиболее оптимальным вариантом решения нашей задачи будет сокрытие всех свойств класса и реализация методов доступа к ним через методы (см. листинг 3.7).
Листинг 3.7. Задание областей видимости.
Третий подход (оптимальный)
unit UsingPrivate3; {Заголовок модуля}
Interface
Туре
АВСЗ = class
private
a, b, с: Double; {Все свойства имеют узкую область видимости}
public
Procedure SetA(NewA: Double);
{Все методы имеют широкую область видимости}
Procedure SetB(NewB: Double);
Function GetC: Double;
end;
Implementation
Procedure ABC3.SetA(NewA: Double);
{Описание метода SetA класса АВС3}
Begin
a:= NewA;
с:= a * b;
end;
Procedure АВСЗ.SetB(NewB: Double);
{Описание метода SetB класса АВС3}
Begin
b:= NewB;
с:= a * b;
end;
Function ABC3.GetC: Double;
{Описание метода GetC класса АВС3)
Begin
Result:= с; {Просто возвращаем значение с}
end;
end.
Дата публикования: 2014-11-02; Прочитано: 740 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!