Board index » delphi » Polymorphism woes

Polymorphism woes

Hello all,

The example code below always ends up calls TB.Foo whenever TA.DoIt is
called -- which it should.  However, I want to change it so TA.Foo is
called instead when TA.DoIt is called.  I've tried everything I can think
of, including:

Self.Foo;
TA(Foo);

But TB.Foo keeps getting called. Any ideas?

Thanks,

Fred

type
  TA = class
    procedure foo; virtual;
    procedure DoIt;
  end;

  TB = class(TA)
    procedure foo; override;
  end;

procedure TA.Foo;
begin
  //Do something
end;

procedure TA.DoIt;
begin
  Foo;
end;

procedure TB.Foo;
begin
  //Do something else
end;

var
  B : TB;

begin
  B := TB.Create;
  B.DoIt;
end;

 

Re:Polymorphism woes


The simple answer is to take the virtual and override qualifiers off of
TA.Foo and TB.Foo, respectively, but I take it you probably want
polymorphism to kick in sometimes; just not in this particular instance
(DoIt).  Typecasting doesn't work for you because all it's doing is
defeating typechecking, not changing the RTTI on the object.

AFAIK, you can't make Foo virtual and non-virtual conditionally, which
seems like what you want.  But I imagine you want to avoid
code-duplication, so I think what I'd do is something like this:

  TA = class(TObject)
    procedure DoIt;
    procedure Foo; virtual;
    procedure FooNonVirtual;
  private
    procedure FooStuff;
  end;
  TB = class(TA)
    procedure Foo; override;
  end;

  procedure TA.FooStuff;
  begin
        // whatever you wanted to do in original TA.Foo

  procedure TA.Foo;
  begin
        FooStuff;
  end;

  procedure TA.FooNonVirtual;
  begin
        FooStuff;
  end;

  procedure TA.DoIt;
  begin
    FooNonVirtual;
  end;

I tad inelegant, perhaps, but it works.  Hope this helps.

Maybe someone else will have a better solution...

Fred Bulback <fred.bulb...@{*word*104}store.ca> wrote in article
<01bc3498$70faf6e0$19c7afc7@fred>...

Quote
> Hello all,

> The example code below always ends up calls TB.Foo whenever TA.DoIt is
> called -- which it should.  However, I want to change it so TA.Foo is
> called instead when TA.DoIt is called.  I've tried everything I can think
> of, including:

> Self.Foo;
> TA(Foo);

> But TB.Foo keeps getting called. Any ideas?

> Thanks,

> Fred

> type
>   TA = class
>     procedure foo; virtual;
>     procedure DoIt;
>   end;

>   TB = class(TA)
>     procedure foo; override;
>   end;

> procedure TA.Foo;
> begin
>   //Do something
> end;

> procedure TA.DoIt;
> begin
>   Foo;
> end;

> procedure TB.Foo;
> begin
>   //Do something else
> end;

> var
>   B : TB;

> begin
>   B := TB.Create;
>   B.DoIt;
> end;

Re:Polymorphism woes


Quote
Fred Bulback wrote:

> Hello all,

> The example code below always ends up calls TB.Foo whenever TA.DoIt is
> called -- which it should.  However, I want to change it so TA.Foo is
> called instead when TA.DoIt is called.  I've tried everything I can think
> of, including:

> Self.Foo;
> TA(Foo);

> But TB.Foo keeps getting called. Any ideas?

> Thanks,

> Fred

> type
>   TA = class
>     procedure foo; virtual;
>     procedure DoIt;
>   end;

>   TB = class(TA)
>     procedure foo; override;
>   end;

> procedure TA.Foo;
> begin
>   //Do something
> end;

> procedure TA.DoIt;
> begin
>   Foo;
> end;

> procedure TB.Foo;
> begin
>   //Do something else
> end;

> var
>   B : TB;

> begin
>   B := TB.Create;
>   B.DoIt;
> end;

Try
  inherited Foo;
or
  TA.Foo;

I think either should work.

Chris Jobson

Other Threads