Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Абстрактные классы в Delphi

#ооп #delphi #object_pascal


Допустим, есть базовый класс. В нем объявляем abstract virtual функцию. В наследнике
реализуем эту функцию (перекрываем override). Вопрос: можно ли вызывать эту функцию
в базовом классе?
ПС: Спрашиваю потому, что встретился с такой ситуацией в чужом коде. До этого думал,
что это невозможно.
    


Ответы

Ответ 1



Можно. Смысл в том, что экземпляров базового абстрактного класса у вас никогда не будет. Будет экземпляр конкретного дочернего класса, в котором этот метод точно переопределен. Этот шаблон проектирования, кстати, называется Шаблонный метод (Template method): в базовом абстрактном классе мы собираем некоторый алгоритм из абстрактных методов. И уже от дочерних конкретных классов будет зависеть работа этого алгоритма. Пример: в базовом классе TCocktail определяется процедура приготовления коктейля. Дочерние классы реализуют конкретные этапы этого процесса. Базовый класс: type TCocktail = class protected procedure AddFirstIngridient(); virtual; abstract; //Добавление первого ингридиента procedure AddSeconsIngridient(); virtual; abstract; //Добавление второго ингридиента procedure AddDecorations(); virtual; abstract; //Добавление украшений function GetName(): string; virtual; abstract; //Название public procedure Prepare; //Алгоритм приготовления коктейля end; { TCocktail } procedure TCocktail.Prepare; begin writeln('Готовим коктейль ' + GetName()); AddFirstIngridient(); AddSeconsIngridient(); AddDecorations(); writeln('Ваш коктейль готов'); end; Первый коктейль type TBloodyMary = class (TCocktail) protected procedure AddFirstIngridient();override; procedure AddSeconsIngridient();override; procedure AddDecorations();override; function GetName(): string;override; end; { TBloodyMary } procedure TBloodyMary.AddDecorations; begin writeln('Добавляем лед'); end; procedure TBloodyMary.AddFirstIngridient; begin writeln('50мл водки'); end; procedure TBloodyMary.AddSeconsIngridient; begin writeln('150мл томатного сока'); end; function TBloodyMary.GetName: string; begin result := 'Кровавая Мэри'; end; Второй коктейль type TIrishCoffee = class (TCocktail) protected procedure AddFirstIngridient();override; procedure AddSeconsIngridient();override; procedure AddDecorations();override; function GetName(): string;override; end; { TBloodyMary } procedure TIrishCoffee.AddDecorations; begin writeln('50 сливки (33%)'); end; procedure TIrishCoffee.AddFirstIngridient; begin writeln('50мл ирландского виски'); end; procedure TIrishCoffee.AddSeconsIngridient; begin writeln('80мл кофе'); end; function TIrishCoffee.GetName: string; begin result := 'Ирландский кофе'; end; Ну и сам код: var cocktail: TCocktail; begin cocktail := TBloodyMary.Create; cocktail.Prepare; cocktail := TIrishCoffee.Create; cocktail.Prepare; readln; end.

Ответ 2



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

Комментариев нет:

Отправить комментарий