Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Инкапсуляция и свойства объектов.




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

Для реализации инкапсуляции в Object Pascal предусмотрена специальная конструкция. В Delphi пользователь объекта может полностью отторжен от его полей при помощи свойств. Свойства обычно характеризуются 3-мя элементами: поле и 2-мя методами, один из которых производит чтение информации из этого поля, а другой производит запись.

type

TAnObject = class (TObject)

function GetAProperty: TSomeType;

procedure SetAProperty (NewValue: TSomeType);

property AProperty: TSomeType read GetAValue write SetAValue;

end;

В этом примере запись и чтение информации свойств осуществляется двумя методами. В написании этих методов в явном виде в программе нет необходимости. Достаточно указать

AnObject.AProperty:=AValue;

AVariable:=AnObject.Aproperty;

Компилятор сам оттранслирует эти операторы вызовом соответствующих методов. Свойство внешне выглядит как поле, однако за каждым обращением к нему могут стоять вызовы внешних методов.

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

type

TPropObject = class (TObject)

FValue: integer;

procedure DoSomehing

function Correct (AValue: integer): Boolean;

procedure SetValue (NewValue: integer);

property AValue: integer read FValue write SetValue;

end;

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

type

TPropObject = class (TObject)

function GetAValue: TSomeType;

property AValue: TSomeType read GetAValue;

end;

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

Для установки значения свойства по умолчанию используют ключевое слово default.

property FVisible: true read GetFVisible write SetFVisible default true;

Это означает, что при запуске программы компилятором будет присвоено??. Свойство может быть и векторным. В этом случае внешне оно будет выглядеть как массив.

Property APoint (Index: integer): TPoint read GetPoint write SetPoint;

Хотя в реальности среди полей класса может и не быть полей типа массив. При помощи свойств вся обработка обращений к внутренним структурам класса может быть замаскирована. При использовании векторного свойства помимо задания??. В случае применения векторного свойства после слов read и write должны стоять имена методов. Применение имен полей в этом случае является недопустимым. Метод, читающий значение векторного свойства должен быть описан, как функция, возвращающая значение того же типа?? и тип которого должны совпадать с именем и типом индекса векторного свойства.

function GetPoint (Index: integer): TPoint;

По аналогии метод, производящий запись в векторное свойство должен быть описан как процедура с 2-мя параметрами. Первый параметр равносилен с именем и типом индекса векторного свойства. Тип второго равносилен с типом элемента векторного свойства.

procedure SetPoint (Index: integer; NewPoint: TPoint);

 

Лекция 3.

У векторных свойств есть еще одна важная особенность. В некоторых важных классах DELPHI (списки, наборы строк) построены вокруг одного векторного свойства. В этом случае один из методов такого класса дает доступ к некоторому массиву элементов, а остальные методы являются вспомогательными. Для облегчения написания программ такой метод может быть описан с использованием ключевого слова default.

type

TMyObject = class (TObject)

property Strings (Index: integer): string read Get write Pul default;

end;

Если в классе есть default-свойство, то при написании программы можно не указывать, а сразу ставить индекс?

var

AMyObject: TMyObject;

AMyObject.Strings[1]:= ‘первый способ’;

AMyObject[2]:= ‘второй способ’;

В DELPHI 100% полей стандартных классов не доступно и заменены базирующимися на их основе свойствами. При разработке собственных классов рекомендуется придерживаться этого правила.

 

Наследование.

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

type TNewObject = class (TOldObject)

end;

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

type

TMyObject = class;

end;

аналогично

type

TMyObject = class (TObject)

end;

Последняя запись является предпочтительней, т.к. устраняет неоднозначности. Все поля и методы, описанные в родительском классе доступны в классе-потомке без каких-либо ограничений. При этом если имена методов совпадают, то о таких методах говорят, что они перекрываются. Исключать члены родительских классов из списка наследования нельзя. В языке Object Pascal не допускается множественное наследование (объект наследует методы и поля от нескольких объектов). В зависимости от своего поведения при наследовании методы разделяются на 3 группы:

¨ Статические

¨ Виртуальные и динамические

¨ Перегружаемые (overload)

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

type

TFirstObject = class (TObject)

i: extended;

procedure SetData (AValue: extended);

end;

TSecondObject = class (TFirstObject);

i: integer;

procedure SetData (AValue: integer);

end;

 

TFirstObject.SetData

begin

i:=1.0;

end;

TSecondObject.SetData

begin

i:=1;

inherited SetData (0,99);

end;

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

В отличие от статических виртуальные и динамические методы. Для того, чтобы метод сделать виртуальным или динамическим нужно указать соответствующую директиву virtual, dynamic. С точки зрения принципа наследования поведение обеих видов методов одинаково. В классе-потомке могут быть перекрыты одноименными методами имеющими тот же тип. Применение виртуальных и динамических методов связано с 3-им свойством объектно-ориентированного программирования – полиморфизмом.

 

Полиморфизм.

 

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...