Jump to content
Sign in to follow this  
pyscripter

Class properties

Recommended Posts

I tried to do something like

class Test
protected
  class function GetValue: string; virtual;
public
  class property Value: string read GetValue;
end;

and I got a compiler error message stating the class property read specifier has to be either a class var or a static class method.   Any idea about the reason for this restriction?

Edited by pyscripter

Share this post


Link to post

Class properties are static and thus cannot have virtual getters or setters. That is because static members have no information about the actual class they are called on. They only know the class they are declared in.

Share this post


Link to post
3 hours ago, Uwe Raabe said:

Class properties are static

You access class properties through a class or an instance reference.  That reference could be passed to a virtual class getter. Why do they have to be static?  This is my question.

A related question.  How do virtual class methods work? Is there an equivalent to VMT for classes?

 

By the way this works correctly:

class Test
protected
  class function GetValue: string; virtual;
public
  property Value: string read GetValue;
end;

i.e. a normal property with a virtual class getter

Edited by pyscripter

Share this post


Link to post
1 hour ago, pyscripter said:

You access class properties through a class or an instance reference. 

ok, this is weird.

 

the "through instance reference" is just a fake, an alias to a call to the static methods. that should not exist in the language.

 

 

Edited by Attila Kovacs

Share this post


Link to post
2 hours ago, pyscripter said:

Why do they have to be static?  This is my question.

They are static by design. The why I cannot answer. Unfortunately there is nothing we can do about it.

 

Instead class properties you may have to switch to class functions. These can be virtual.

Share this post


Link to post
28 minutes ago, Uwe Raabe said:

They are static by design. The why I cannot answer. Unfortunately there is nothing we can do about it.

This looks like an inconsistency in the language with regard to class methods and class properties.  And I don't think it is documented.

 

Share this post


Link to post

The issue is that for anything 'virtual' to work, a VMT needs to be available. Virtual methods are accessible on instances of a class through the class VMT. 

 

The only way to accomplish something like what you wanted would be to introduce some helper variables/procedures in delphi/pascal to accomplish this - something that is overly verbose in pascal compared to python. I've given an example below.

 

From a python perspective, you would maybe have something like:

class X:
    @staticmethod
    def do_something():
        return '42'

print(X.do_something()) # 42

# illustrating overriding with a lambda
X.do_something = lambda: '43'
print(X.do_something()) # 43

 

In Delphi, you could do the following:

type
   TMyGetter = function : string;
   TTest = class
    private
       class var FValueGetter: TMyGetter;     
       class function GetValue:string;
    public
       class constructor Create;
       class property ValueGetter: TMyGetter read FValueGetter write FValueGetter;
       class property Value : string read GetValue;
   end;

function MyGetValue:string;
begin
   exit('42');
end;
function MyGetValue2:string;
begin
   exit('43');
end;
class constructor TTest.Create;
begin
    TTest.FValueGetter := MyGetValue;
end;
class function TTest.GetValue:string;
begin
    if assigned(TTest.FValueGetter) then begin
       result := TTest.FValueGetter();
       exit;
     end;
     raise Exception.Create('no getter set');
end;

begin
    writeln(TTest.Value); // 42
    
    TTest.ValueGetter := MyGetValue2;
    writeln(TTest.Value); // 43 
end. 

In the above the the 'ValueGetter' sort of provides the same behaviour of the VMT in allowing it to be overridden. However, this is not a polymorphic property - so inheritance does not work... child classes would essentially modify the same static variable - but this principle applies the same way for my python example above as well I think.

Edited by darnocian

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  

×