Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ВВЕДЕНИЕ В ОБЪЕКТНО Ориентированное программиро...docx
Скачиваний:
19
Добавлен:
29.08.2019
Размер:
1.01 Mб
Скачать

Абстрактные методы

Абстрактными называются виртуальные и динамические методы, которые определены в классе, но не содержат никаких действий, никогда не вызываются и обязательно должны быть переопределены в потомках класса. Абстрактными могут быть только виртуальные и динамические методы, В Object Pascal для объявления метода абстрактным при его описании используется директива abstract после директивы virtual или dynamic:

TOb = class

Procedure X; virtual; abstract;

end;

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

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

Перегрузка методов

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

Для того, что бы объявить метод перегружаемым используется директива overload Рассмотрим пример:

Вторая строка вызовет ошибку компиляции. Для компилятора внутри Т2 статический метод с параметром типа real перекрыт, и он его не признает. Какие возможны выходы: переименовать метод - но если их не два, а сто то может возникнуть путаница; сделать метод виртуальным - нельзя, так как не совпадает тип параметров. Для решения этой проблемы существуют перегружаемые методы:

Объявив метод SetData перегружаемым в программе можно использовать обе его реализации одновременно. Компилятор будет различать, какой из них вызвать по типу передаваемого параметра. Причем различия именно в параметрах, а не в возвращаемых значениях. Следующий пример вызовет ошибку компиляции:

Не обязательно описывать разные реализации перегружаемых методах в разных классах. Следующее определение класса также допустимо:

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

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

Сравним действие директивы reintroduce отдельно и вместе с директивой overload.

Первый вариант:

type

TObl = class

procedure Met; overload; virtual;

end;

T0b2 = class(TObl)

procedure Met(s:string); reintroduce;

end;

var

Ob:TOb2;

Ob :T0b2.Create;

Ob.Met; // Вызовет ошибку компиляции, так как метод статически перекрыт

Ob.Met(‘текст');

Второй вариант:

type

TObl = class

procedure Met; overload; virtual;

end;

T0b2 = class (TObl)

procedure Met(s:string); reintroduce; overload;

end;

var

Ob:TOb2;

Ob := T0b2.Create;

Ob.Met; //He вызовет ошибку компиляции

Ob.Met ( ‘текст’) ;

На перегрузку методов наложены ограничения: нельзя перегружать методы, которые объявлены как read и write для свойства. И нельзя перегружать методы, находящиеся в области видимости published. Области видимости будут рассмотрены позднее. При вызове перегружаемых методов, так же как и обычных, допустимо использование типов, не идентичных объявленным, но совместимых с ними при объявлении формального параметра подпрограммы типа Real1 можно передавать фактический параметр типа integer. Но это делает допустим вызов нескольких методов. В таком случае, когда это возможно сделать без двусмысленности, будет вызван тот метод, чьи параметры типа, имеющего наименьший диапазон, вмещающий фактический параметр.