|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Поскольку интерфейс не может содержать поля, все его свойства отображены на его методыПоддержка интерфейса классом Интерфейс бесполезен до тех пор, пока он не реализован. Реализацией интерфейса занимается класс. Если класс реализует интерфейс, то интерфейс может использоваться для доступа к объектам этого класса. При объявлении класса имя реализуемого интерфейса записывается через запятую после имени базового класса: TTextReader = class(TObject, ITextReader) Такая запись означает, что класс TTextReader унаследован от класса TObject и реализует интерфейс ITextReader. Класс, реализующий интерфейс, должен содержать код для всех методов интерфейса. Методы QueryInterface, _ AddRef и _ Release, которые тоже должны быть реализованы. К счастью, вам нет необходимости ломать голову над реализацией этих методов, поскольку разработчики системы Delphi уже позаботились об этом. Стандартная реализация методов интерфейса IInterface находится в классе TInterfacedObject. TTextReader = class(TInterfacedObject, ITextReader)
При наличии в интерфейсах нескольких одинаковых функций:
function NetxItem: String; function IStringIterator.Next:= NextItem;
Механизм подсчета ссылок в интерфейсах Механизм подсчета ссылок на объект предназначен для автоматического уничтожения неиспользуемых объектов. Неиспользуемым считается объект, на который не ссылается ни одна интерфейсная переменная. Подсчет ссылок на объект обеспечивают методы _ AddRef и _ Release интерфейса IInterface. При копировании значения интерфейсной переменной вызывается метод _ AddRef, а при уничтожении интерфейсной переменной – метод _ Release. Вызовы этих методов генерируются компилятором автоматически.
Var Intf, Copy: IInterface; Begin Copy:= Intf; // Copy._Release; Intf._AddRef; Intf:= nil; // Intf._Release; End; // Copy._Release Стандартная реализация методов _ AddRef и _ Release находится в классе TInterfacedObject. Type TInterfacedObject = class(TObject, IInterface) ... FRefCount: Integer; // Счетчик ссылок function_AddRef: Integer; stdcall; function_Release: Integer; stdcall; ... end; function TInterfacedObject._AddRef: Integer; Begin Result:= InterlockedIncrement(FRefCount); // Увеличение счетчика ссылок end; function TInterfacedObject._Release: Integer; Begin Result:= InterlockedDecrement(FRefCount); // Уменьшение счетчика ссылок If Result = 0 then // Если ссылок больше нет, то Destroy; // уничтожение объекта end; Функции InterlockedIncrement и InterlockedDecrement просто увеличивают значение целочисленной переменной на единицу. В отличие от обычного оператора сложения, они обеспечивают атомарное изменение значения переменной, что очень важно для правильной работы многопоточных программ. Var Obj: TDelimitedReader; Intf, Copy: ITextReader; Begin Obj:= TDelimitedReader.Create('MyData.del', ';'); Intf:= Obj; // Obj._AddRef -> Obj.FRefCount = 1 Copy:= Intf; // Obj._AddRef -> Obj.FRefCount = 2 ... Intf:= nil; // Obj._Release -> Obj.FRefCount = 1 Copy:= nil; // Obj._Release -> Obj.FRefCount = 0 -> Obj.Destroy Obj.Free; // Ошибка! Объект уже уничтожен и переменная Obj указывает в никуда end; Обратите внимание, что объектные переменные не учитываются при подсчете ссылок. Поэтому мы настоятельно рекомендуем избегать смешивания интерфейсных и объектных переменных. Если вы планируете использовать объект через интерфейс, то лучше всего результат работы конструктора сразу присвоить интерфейсной переменной: Var Intf: ITextReader; Begin Intf:= TDelimitedReader.Create('MyData.del', ';'); // FRefCount = 1 ... Intf:= nil; // FRefCount = 0 -> Destroy end;
Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.004 сек.) |