Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ООП.doc
Скачиваний:
23
Добавлен:
08.11.2018
Размер:
1.4 Mб
Скачать
  1. Перегрузка методов

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

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

Для того, что бы объявить метод перегружаемым в Object Pascal используется директива overload. Перегружать методы можно как внутри одного класса, так и в классах-потомках:

Type T1 = class(TObject) procedure Test(i: integer); overload; procedure Test(s: string); overload; end; T2 = class(T1) procedure Test(r: real); overload; end;

Рассмотрим пример. У двух классов, связанных отношением наследования есть разнотипные данные, и есть метод, который устанавливает значение этих данных SetData. Сначала попытаемся обойтись без использования механизма перегрузки:

Type TOb1 = class (TObject) r: real; procedure SetData(AValue: real); end;

TOb2 = class(TOb1) c: char; procedure SetData(AValue: char); end;

...

Procedure Test; var T1: TOb1; T2: TOb2; begin T1 := TOb1.Create; T2 := TOb2.Create; T1.SetData(1.1); //допустимо //T2.SetData(1.1); //не допустимо T2.SetData(‘1’); //допустимо ... T1.Free; T2.Free; end;

Строка T2.SetData(1.1) вызовет ошибку компиляции. Для компилятора внутри класса TOb2, к которому принадлежит объект Т2, метод SetData с параметром типа real перекрыт статически, методом с параметром типа char. Следовательно, такой путь неприменим. Рассмотрим, какие возможны выходы. Первый – дать методам разные имена. Но если методов не два, а сто, то может возникнуть путаница. Второй – сделать метод SetData перегружаемым.

В этом случае пример будет выглядеть так:

Type TOb1 = class(TObject) r: real; procedure SetData(AValue: real); overload; end;

TOb2 = class(TOb1) c: char; procedure SetData(AValue: char); overload; end;

...

Procedure Test; var T1: TOb1; T2: TOb2; begin T1 := TOb1.Create; T2 := TOb2.Create; T1.SetData(1.0); //допустимо T2.SetData(1.0); //допустимо T2.SetData(‘1’); //допустимо ... T1.Free; T2.Free; end;

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

Объявить перегружаемые методы SetData можно и внутри одного класса:

Interface type TDat = class private r: real; i: integer; s: string; ... public procedure SetData(AValue: real); overload; procedure SetData(AValue: integer); overload; procedure SetData(AValue: string); overload; ... end;

implementation procedure TDat.SetData(AValue: real); begin r := AValue; end;

procedure TDat.SetData(AValue: integer); begin i := AValue; end;

procedure TDat.SetData(AValue: string); begin s := AValue; end;

...

procedure Test; var T: TDat; begin T := TDat.Create; ... T.SetData(1.0); //допустимо T.SetData(1); //допустимо T.SetData(‘1’); //допустимо ... T.Free; end;

В этом примере в разных случаях будет установлено значение разных полей.

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

Type TOb1 = class(TObject) function F(): real; overload; ... end;

TOb2 = class(TOb1) //function F(): char; overload; //ошибка компиляции, поскольку изменения только //типа возвращаемого значения недостаточно для перегрузки ... end;