Suppose there is a base class. In it we declare an abstract virtual function. In the successor, we implement this function (overlap override). Question: Is it possible to call this function in the base class? PS: I ask because I have met with such a situation in someone else's code. Before that I thought it was impossible.

    2 answers 2

    Can. The point is that you will never have an instance of a base abstract class. There will be an instance of a specific child class in which this method is exactly overridden.

    This design pattern, by the way, is called the Template method: in the base abstract class we collect some algorithm from the abstract methods. And the work of this algorithm will depend on the child specific classes.


    Example: TCocktail base class defines a cocktail preparation procedure. Child classes implement the specific steps of this process.

    Base class:

    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; 

    First cocktail

     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; 

    Second cocktail

     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; 

    Well, the code itself:

     var cocktail: TCocktail; begin cocktail := TBloodyMary.Create; cocktail.Prepare; cocktail := TIrishCoffee.Create; cocktail.Prepare; readln; end. 
    • Is it possible to have a minimal example? - Sh4dow
    • plus two) - Sh4dow

    The call to the overlapped parent method is performed by the inherited service word.

    • one
      Not at the cashier. The question is not about calling an overlapped parent method from a child class, but about calling an implementing child from a parent. - Nofate ♦
    • Oops, I'm sorry, I did not carefully read the question. - toxicdream