Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Ограничение видимости элементов класса
Класс TPerson содержит четыре элемента класса – два поля и два метода. И поля, и методы без затруднений доступны из любого объекта: var Man: TPerson; ... Man.SetAge(36); // работа с полем через метод Man.fAge: = -100; // непосредственная работа с полем Приведённый пример показывает недостаток подобной свободы. Одно из назначений метода TPerson.SetAge – корректная установка возраста. Вместе с тем этот метод можно обойти, установив возраст прямо через поле. В Object Pascal существуют специальные директивы ограничения видимости, которые при описании класса позволяют контролировать видимость его элементов. Эти директивы разделяют объявление класса на секции видимости. Рассмотрим две директивы – private и public. Все элементы класса из секции private доступны для использования только в том модуле или программе, которые содержат объявление класса. В секции private обычно размещаются поля и методы, описывающие внутренние особенности реализации класса. Элементы из секции public не имеет ограничений на использование. Подчеркнём следующие особенности использования директив. Во-первых, внутри модуля с описанием класса директивы ограничения видимости не действуют. Во-вторых, по умолчанию для элементов класса установлена директива видимости public. И, наконец, порядок директив в описании класса произволен, допускается повторение директив. Однако принято описывать элементы класса в порядке увеличения открытости. Применим директивы private и public к классу TPerson, поместив его в отдельный модуль. Обратите внимание: описание класса помещено в секцию interface, а реализация – в секцию implementation: unit TPersonClass; interface
type TPerson = class private fName: string; fAge: Integer; public procedure SetAge(Age: Integer); function SayName: string; end;
implementation
procedure TPerson.SetAge(Age: Integer); begin if Age > 0 then fAge: = Age end;
function TPerson.SayName: string; begin Result: = 'My name is ' + fName end; end. Теперь попытка обратится к полю fAge в программе, использующей класс TPerson, вызовет ошибку компиляции: program OOPProgramm; uses TPPersonClass
var Man: TPerson; ... Man.fAge: = -100; // ошибка компиляции! Таким образом, при помощи директив поля класса защищены от «вторжения» пользователей. Однако теперь у TPerson появился недостаток – значения полей нельзя прочитать непосредственно. Этот недостаток устраняется введением в класс дополнительных методов. В общем случае в ООП принято осуществлять доступ к полям только через методы класса. Говорят, что такие методы составляют интерфейс класса. type TPerson = class private fName: string; fAge: Integer; public procedure SetAge(Age: Integer); function GetAge: Integer; procedure SetName(Name: string); function SayName: string; end; Обсудим преимущества, которые даёт использование методов для доступа к полям. Первое преимущество: при использовании методов данные объекта могут быть представлены в разных форматах без дублирования. Для иллюстрации рассмотрим простой класс TTemperature, назначение которого – хранить данные о температуре. В классе будет использоваться две пары методов для чтения и записи поля, что позволит получать температуру в двух вариантах – градусах Цельсия и кельвинах: type TTemperature = class private fTemp: double; public procedure SetTempCelsius(Temp: double); function GetTempCelsius: double; procedure SetTempKelvin(Temp: double); function GetTempKelvin: double; end; ... procedure TTemperature.SetTempCelsius; begin fTemp: = Temp + 273.15 end;
function TTemperature.GetTempCelsius; begin Result: = Temp - 273.15 end;
procedure TTemperature.SetTempKelvin; begin fTemp: = Temp end;
function TTemperature.GetTempKelvin; begin Result: = Temp end; ... var T: TTemperature; ... T.SetTempCelsius(20); // установили в градусах Цельсия A: = T.GetTempKelvin; // прочитали в кельвинах Второе преимущество использования методов для доступа к полям класса: разработчик класса может незаметно для пользователей изменять структуру хранения данных класса. Например, в классе TTemperature мы могли бы хранить температуру в градусах Цельсия. Для этого нам пришлось бы переписать методы класса. Но если оставить их заголовки прежними, пользователь класса подобной замены не увидит. Подводя итог, можно сформулировать следующее правило: создатель класса должен исключить возможность прямой работы с полями – для этого следует использовать набор интерфейсных методов.
|