tags:

views:

574

answers:

3

Is it possible in Delphi to have a class method invoke an inherited instance method with the same name? For example, I tried something like this:

//... Skipped surrounding class definitions

function TSomeAbstractDialogForm.Execute: Boolean;
begin
  Result := ShowModal = mrOk;
end;

I had a couple of specialized dialog classes that inherited the abstract dialog form, and each class had its own factory method:

class function TSomeInheritingDialogForm.Execute: Boolean;
var
  Fm: TSomeInheritingDialogForm;
begin
  Fm := TSomeInheritingDialogForm.Create(nil);
  try
    Result := Fm.Execute;
  finally
    Fm.Free;
  end
end;

This approach resulted in a never ending loop since F.Execute, instead of invoking the intended instance method of the base class, kept calling the factory method over and over again (resulting in a pile of created forms).

Of course, the obvious solution was to change the name of the factory method (I named it CreateAndShow), but it made me curious. How come the compiler didn't warn me about the hidden method? And is there a way to explicitly invoke the instance method in a situation like this?

+4  A: 

You can try a hard cast. But it is better to rename the class function. (For example to CreateAndExecute).

The Execute in the child class hides the execute in the parent class (I think the compiler will give a warning for that). You can access this with a hard cast. But there is no way to distinguish between an instance method and a class method.

function TSomeAbstractDialogForm.Execute: Boolean;
begin
  Result := ShowModal = mrOk;
end;

class function TSomeInheritingDialogForm.Execute: Boolean;
var
  Fm: TSomeInheritingDialogForm;
begin
  Fm := TSomeInheritingDialogForm.Create(nil);
  try
    Result := TSomeAbstractDialogForm(Fm).Execute;
  finally
    Fm.Free;
  end
end;
Gamecat
Ah, of course, cast to base class. Obvious. Why didn't I think of that? :-)The compiler didn't warn me and I found that somewhat strange. Delphi seems to miss the special case of class methods hiding instance methods.
Hans-Eric
A: 

Wouldn't

Result := inherited Execute;

do the trick?

you mean something like this "result := inherited Fm.Execute;" or is it "result := FM.inherited Execute;"? Anyway, seems much too confusing, IMHO.
Uwe Raabe
Inherited could also work: result := inherited; or result := inherited Execute;
Gamecat
+1  A: 

Result := inherited Execute will not do since it is called on created variable, and not in class method.

The problem is that it's a bad idea to have class function and static method with same name. Compiler is treating them as two separate worlds, that can be written near to each other.

dmajkic