Board index » delphi » Sticking to class (ancestor) level

Sticking to class (ancestor) level

I am sure there are thousands of better alternatives to this approach, but I was wondering whether
there is an elegant way to make a class method call another class method within the same ancestor
level, instead of going for the youngest offspring.

Example:

TParentClass = class
protected
  class procedure DoSomething; virtual;
  class procedure DoSomethingExtra; virtual;
end;

TChildClass = class(TParentClass)
protected
  class procedure DoSomething; override;
  class procedure DoSomethingExtra; override;
end;

Code:

procedure TParentClass.DoSomething;
begin
  DoSomethingExtra
end;

procedure TChildClass.DoSomething;
begin
  inherited;
  // non-relevant extra code
end;

How can I easily achieve that when the inherited part in TChildClass.DoSomething is executed, the
DoSomethingExtra method call in TParentClass.DoSomething calls the TParentClass.DoSomethingExtra
method and not TChildClass.DoSomethingExtra.

I know I can resolve this by, for instance, putting some of the code in the private part, or by
carrying out class checking in the inherited DoSomethingExtra method, but I was wondering whether
there is a way to force a class method call to remain within its own class?

Many thanks.

Cheers,
Dom

 

Re:Sticking to class (ancestor) level


Quote
In article <39c6376f$1_1@dnews>, Dominique Willems wrote:
> I am sure there are thousands of better alternatives to this approach, but I was wondering whether
> there is an elegant way to make a class method call another class method within the same ancestor
> level, instead of going for the youngest offspring.

> Example:

-snip-

The solution is to simple make DoSomethingextra static, not virtual.

Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitly requested!

Re:Sticking to class (ancestor) level


"Peter Below (TeamB)" <100113.1...@compuXXserve.com>
 > The solution is to simple make DoSomethingextra static, not virtual.

Many thanks for your reply.
I forgot to mention, however, that DoSomethingExtra implements (descends from and implements) an
abstract method, hence I can't make it static.

Dom

Re:Sticking to class (ancestor) level


"Dominique Willems" <do...@compuserve.com> wrote
Quote
> I forgot to mention, however, that DoSomethingExtra implements (descends from and implements) an
> abstract method, hence I can't make it static.

Bull. Ignore my ramblings and many thanks for the assistance! :)

Cheers,
Dom

Re:Sticking to class (ancestor) level


Quote
Dominique Willems wrote...
>I forgot to mention, however, that DoSomethingExtra implements (descends from and implements) an
>abstract method, hence I can't make it static.

In that case, do not override DoSomethingExtra in the derived class, only
in the parent class (which descends from the abstract class, I hope).
--
Rudy Velthuis (Team JEDI)
http://delphi-jedi.org

Re:Sticking to class (ancestor) level


Quote
Dominique Willems wrote...
>Bull. Ignore my ramblings and many thanks for the assistance! :)

Wait... we want to know to what conclusion you have come.

And commercials for Bull should go to thirdpartytools. <g>
--
Rudy Velthuis (Team JEDI)
http://delphi-jedi.org

Re:Sticking to class (ancestor) level


"Rudy Velthuis (Team JEDI)" <rvelth...@gmx.de>
Quote
> Wait... we want to know to what conclusion you have come.

It's a mess at the moment, Rudy. I posted an extreme simplification of the problem and am currently
gathering the courage to construct a complete example of what I am doing. It involves dynamically
created class references, and with the static solution proposed the methods being called fall back
onto the abstract ancestor.

Trying to focus my mind for a change, so that I can post something clear.

Thanks!
Dom

Re:Sticking to class (ancestor) level


"Rudy Velthuis (Team JEDI)" <rvelth...@gmx.de>

Quote
> Wait... we want to know to what conclusion you have come.

It's a mess at the moment, Rudy. I posted an extreme simplification of the problem and am currently
gathering the courage to construct a complete example of what I am doing. It involves dynamically
created class references, and with the static solution proposed the methods being called fall back
onto the abstract ancestor.

Trying to focus my mind for a change, so that I can post something clear.

Thanks!
Dom

Re:Sticking to class (ancestor) level


Here's the deal:

TGrandFatherClass = class
  class procedure DoSomething; virtual; abstract;
  class procedure DoSomethingExtra; virtual; abstract;
end;

TParentClass = class(TGrandFatherClass)
protected
  class procedure DoSomething; override;
  class procedure DoSomethingExtra; override;
end;

TChildClass = class(TParentClass)
protected
  class procedure DoSomething; override;
  class procedure DoSomethingExtra; override;
end;

Code:

var
  Obj: TGrandFatherClass;

procedure SomeIrrelevantClass.SomeProcedure;
begin
  Obj := TChildClass.Create;
  Obj.DoSomething  ----> executes TChildClass.DoSomething, then TParentClass.DoSomething,
                                    then TChildClass.DoSomethingExtra (which I don't want; I want it
to
                                    execute TParentClass.DoSomethingExtra)...
end;

procedure TParentClass.DoSomething;
begin
  DoSomethingExtra
end;

procedure TParentClass.DoSomethingExtra;
begin
  // Do something useful
end;

procedure TChildClass.DoSomething;
begin
  inherited;
  // non-relevant extra code
end;

procedure TChildClass.DoSomethingExtra;
begin
  inherited;
  // do something useful, but specific to TChildClass
end;

I hope I haven't over-simplified this time.

Thanks,
Dom

Re:Sticking to class (ancestor) level


Quote
Dominique Willems wrote...

Your TChildClass.DoSomethingExtra seems to be made to be called by
TChildClass methods only, so why put it in the inheritance tree? Why not
just create a new method that calls "inherited DoSomethingExtra" instead?

See below:

Quote
>procedure TChildClass.DoSomethingExtra;
>begin
>  inherited;
>  // do something useful, but specific to TChildClass
>end;

Why not get rid of TChildClass.DoSomethingExtra, and create:

procedure TChildClass.DoSomethingEvenMoreExtra; // non-virtual!
begin
  inherited DoSomethingExtra; // explicit call of ancestor method.
  // do something useful, but specific to TChildClass
end;

This way, a call to DoSomethingExtra will always call
TParentClass.DoSomethingExtra, both from the parent and the child class.

IOW: just stop inheritance at the father class, and go on with a new
static method for the child class. This can call "inherited
DoSomethingExtra" explicitly.

--
Rudy Velthuis (Team JEDI)
http://delphi-jedi.org

Re:Sticking to class (ancestor) level


"Rudy Velthuis (Team JEDI)" <rvelth...@gmx.de>

Quote
> Your TChildClass.DoSomethingExtra seems to be made to be called by
> TChildClass methods only, so why put it in the inheritance tree?

Well, TChildClass.DoSomethingExtra is actually a method that is also called from other classes.
These other classes assume the existence of a DoSomethingExtra method as defined in
TGrandFatherClass.

If only there existed a modifier like "this" that could force the method call to occur inside the
current method's class. Something like

"this DoSomethingExtra" would be of great use to me now. :)

Thanks,
Dom

Other Threads