|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Obj: TTextReader; // объектная переменнаяIntf: ITextReader; // интерфейсная переменная Begin ... Intf:= Obj; ... end; После инициализации интерфейсную переменную Intf можно использовать для вызова методов объекта Obj: Intf.Active:= True; // -> Obj.SetActive(True); Через интерфейсную переменную доступны только те методы и свойства объекта, которые есть в интерфейсе: Intf.Free; // Ошибка! У интерфейса ITextReadaer нет методаFree. Obj.Free; // Метод Free можно вызвать только так. Алгоритм вызова метода интерфейса такой же, как алгоритм вызова метода класса. Когда через интерфейсную переменную выполняется вызов метода, Intf.NextLine, реализуется следующий алгоритм: 1) из интерфейсной переменной извлекается адрес (по нему хранится адрес таблицы методов интерфейса); 2) по полученному адресу извлекается адрес таблицы методов интерфейса; 3) на основании порядкового номера метода в интерфейсе из таблицы извлекается адрес соответствующей подпрограммы; Вызывается код, находящийся по этому адресу. Этот код является переходником от метода интерфейса к методу объекта. Его задача – восстановить из ссылки на интерфейс значение указателя Self (путем вычитания заранее известного значения) и выполнить прямой переход на код метода класса.
Обычными средствами процедурного программирования этот алгоритм реализуется так: Type TMethodTable = array[0..9999] ofPointer; TNextLineFunc = function(Self: ITextReader): Boolean; Var Intf: ITextReader; // интерфейсная переменна IntfPtr: Pointer; // адрес внутри интерфейсной переменной TablePtr: ^TMethodTable; // указатель на таблицу методов интерфейса MethodPtr: Pointer; // указатель на метод Begin ... IntfPtr:= Pointer(Intf); // 1) извлечение адреса из интерфейсной Переменной TablePtr:= Pointer(IntfPtr^); // 2) извлечение адреса таблицы методов Интерфейса MethodPtr:= TablePtr^[3]; // 3) извлечение адреса нужного метода из таблицы TNextLineFunc(MethodPtr)(Intf); // 4) вызов метода через переходник ... End. Вызов метода через интерфейс в машинном коде выполняется весьма эффективно (всего несколько инструкций процессора), поэтому в подавляющем большинстве случаев потерями на вызов можно пренебречь. Алгоритм вызова метода интерфейса такой же, как алгоритм вызова метода класса. Когда через интерфейсную переменную выполняется вызов метода, Intf.NextLine, реализуется следующий алгоритм: 1) из интерфейсной переменной извлекается адрес (по нему хранится адрес таблицы методов интерфейса); 2) по полученному адресу извлекается адрес таблицы методов интерфейса; 3) на основании порядкового номера метода в интерфейсе из таблицы извлекается адрес соответствующей подпрограммы; Вызывается код, находящийся по этому адресу. Этот код является переходником от метода интерфейса к методу объекта. Его задача – восстановить из ссылки на интерфейс значение указателя Self (путем вычитания заранее известного значения) и выполнить прямой переход на код метода класса.
Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.003 сек.) |