Jump to content

Recommended Posts

Hi Delphi addicts,

I want to create an "inherited class property".

- I define a class property in Master

- Define a local getter in Master, because a getter must be static

- Define an abstract class procedure, called by the getter

- Implement the class procedure in Child

 

Writing it in Delphi and compiling it, all goes well.

When executing the code, the getter raises an abstract error when calling the class procedure.

 

What am I missing?

Is there a way to define inheritable polymorf class properties?

 

unit Unit1;

interface

type
  TMaster = class
  private
    class function GetMasterId: integer; static; {MUST be a static method for a property getter}
  protected
    class function GetChildID: integer; virtual; abstract;
  public
    class property id: integer read GetMasterId ;
  end;

  TChild = class(TMaster)
  protected
    class function GetChildID: integer; override;
  end;

implementation

{ TMaster }

class function TMaster.GetMasterId: integer;
begin
  result := GetChildID ;   { <= at this point I get an abstract error}
end;

{ TChild }

class function TChild.GetChildID: integer;
begin
  result := 1
end;

end.
procedure TForm2.Button1Click(Sender: TObject);
begin
  Edit1.Text := inttostr(TChild.id)  { <= Calling the Child's property}
end;


 

Share this post


Link to post

The docs give some hints:

Quote

Unlike ordinary class methods, class static methods have no Self parameter at all.

That implies, that they have no idea on which class they are called on and always use the class they are declared in to access any non-static class method.

Unfortunately, what you are trying to achieve is not possible this way. Use a non-static class function instead of a class property.

Share this post


Link to post
12 minutes ago, Uwe Raabe said:

Use a non-static class function

This is exactly what I'm trying to do: 

class function GetChildID: integer; virtual; abstract;

is a virtual class function.

But the Child-version of this class function is not found!

Share this post


Link to post

this is it:

class function TMaster.GetMasterId: integer;
begin
  writeln(classname);
  // Result := GetChildID; { <= at this point I get an abstract error }
end;

 

Share this post


Link to post
44 minutes ago, Sam Witse said:
1 hour ago, Uwe Raabe said:

Use a non-static class function

This is exactly what I'm trying to do: 

You missed to quote my suggestion to the end:

1 hour ago, Uwe Raabe said:

Use a non-static class function instead of a class property.

procedure TForm2.Button1Click(Sender: TObject);
begin
  Edit1.Text := inttostr(TChild.GetChildId)  { <= Calling the Child's class function}
end;

 

  • Like 1

Share this post


Link to post
procedure TForm2.Button1Click(Sender: TObject);
begin
  Edit1.Text := inttostr(TChild.id)  { <= Calling the Child's property}
end;

When you use the above call, TChild.id calls static GetMasterID method. Because that method is static it does not have Self parameter passed, which in context of class methods represents class itself. 

 

So when you are inside GetMasterID method, compiler no longer knows from which class you have called that method. It only knows the class where the method is implemented, in this case TMaster. And calling GetChildID will be interpreted as calling TMaster.GetChildID.

 

If you remove abstract on TMaster.GetChildID and implement that function as regular virtual method, which returns different integer than TChild.GetChildID you will no longer have abstract exception, but you will get wrong results. 

 

  • Like 1

Share this post


Link to post
2 hours ago, Sam Witse said:

Any idea how I could define a working 'polymorfic property' ?

You cannot use property. The only thing you can do is removing property and static getter and renaming virtual getter function to id.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×