Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Virtual Methods 2

Status
Not open for further replies.

roo0047

Programmer
Jul 31, 2004
533
US
I have to brush up on Virtual Methods for an interview. I understand them but got stumped when trying to demonstrate it to myself. First, go here: The example is in C++ so I converted it to delphi.
Code:
unit AnimalUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TAnimal = class
    function eat: string; [RED]//virtual;[/RED]
  end;

  TWolf = class(TAnimal)
    function eat: string;
  end;

  TFish = class(TAnimal)
    function eat: string;
  end;

  TOtherAnimal = class(TAnimal)
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TAnimal.eat: string;
begin
  result:= 'I eat like a generic Animal.'
end;

function TWolf.eat: string;
begin
  result:= 'I eat like a wolf!'
end;


function TFish.eat: string;
begin
  result:= 'I eat like a fish!'
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Animal: TAnimal;
  Wolf: TWolf;
  Fish: TFish;
  OtherAnimal: TOtherAnimal;
begin
  Animal:= TAnimal.Create;
  Wolf:= TWolf.Create;
  Fish:= TFish.Create;
  OtherAnimal:= TOtherAnimal.Create;
  Memo1.Lines.Add(Animal.eat);
  Memo1.Lines.Add(Wolf.eat);
  Memo1.Lines.Add(Fish.eat);
  Memo1.Lines.Add(OtherAnimal.eat);
  Animal.Free;
  Wolf.Free;
  Fish.Free;
  OtherAnimal.Free;
end;

end.
According to this article, removing the [red]//[/red] comment from the code should produce different results, but it doesn't. What am I missing here?

Roo
Delphi Rules!
 
I added a second button to more closely duplicate the C++ example.
Code:
procedure TForm1.Button2Click(Sender: TObject);
var
  AnAnimal: array [0..3] of TAnimal;
  i: integer;
begin
  anAnimal[0]:= TAnimal.Create;
  anAnimal[1]:= TWolf.Create;
  anAnimal[2]:= TFish.Create;
  anAnimal[3]:= TOtherAnimal.Create;
  for i:= 0 to 3 do
    Memo1.Lines.Add(anAnimal[i].eat);
end;
It produces the other result, but with or without the "virtual;". Now I'm really confused!


Roo
Delphi Rules!
 
Ok, adding "override" to function eat; for TWolf and TFish did the trick, but must be removed (or commented out) if "virtual" is removed (or commented out).

I guess that makes sense. I'm just not sure I can explain it. And I've been told the interviewer will be asking me to explain my understanding of polymorphism, inheritance, thread development, and virtual methods. God I hate interviews!!!

"Is There Anybody Out There?"

Roo
Delphi Rules!
 
use virtual & abstract (TAnimal is an abstract class)

and then override...

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
untested but should work:

Code:
unit AnimalUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TAnimal = class
    function eat: string; virtual; abstract;
  end;

  TWolf = class(TAnimal)
    function eat: string; override;
  end;

  TFish = class(TAnimal)
    function eat: string; override;
  end;

  TOtherAnimal = class(TAnimal)
    function eat: string; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TAnimal.eat: string;
begin
 // do nothing here, we are an abstract method
//  result:= 'I eat like a generic Animal.'
end;

function TWolf.eat: string;
begin
  result:= 'I eat like a wolf!'
end;


function TFish.eat: string;
begin
  result:= 'I eat like a fish!'
end;

function TOtherAnimal.eat: string;
begin
  result:= 'I eat like an other animal!'
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Animal: TAnimal;
  Wolf: TWolf;
  Fish: TFish;
  OtherAnimal: TOtherAnimal;
begin
  //Animal:= TAnimal.Create;//abstract class do not use it
  Wolf:= TWolf.Create;
  Fish:= TFish.Create;
  OtherAnimal:= TOtherAnimal.Create;
  Memo1.Lines.Add(Wolf.eat);
  Memo1.Lines.Add(Fish.eat);
  Memo1.Lines.Add(OtherAnimal.eat);
  Wolf.Free;
  Fish.Free;
  OtherAnimal.Free;
end;

end.

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
I wrote a FAQ on when to use virtual methods you may find helpful faq102-6271
 
Thank you both! I'm glad I asked. :p

Roo
Delphi Rules!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top