An uninitialized class constant is a normal constant with the addition of some scope.
The typed class constant is really a class variable that you cannot change.
The problem is that class variables are not virtual.
Halvard Wassbotn wrote about it here: Part 1 , Part 2
You cannot access class variables and class constants from a class reference, because the language does not support virtual class variables.
When you say s:= TClass1.SomeConst , the compiler translates this to s:= SomeGlobalButHiddenConst before moving on to the rest of the compilation.
class var and class const are nothing more than syntactic sugar.
Thus, the connection between class var/const and the actual class exists only at compile time, it is interrupted at runtime, like erasing styles in Java.
RTTI also doesn't help:
Get persistent fields from a class using RTTII think if you are using D2007, your only option is to declare a virtual function that returns the constant you want:
Pre D2010 Parameter: Virtual Method
TParent = class class function Name: string; virtual; end; TChild1 = class(TParent) class function name: string; override; .... class function TParent.name: string; begin Result:= Self.ClassConst; end; class function TChild1.name: string; begin Result:= Self.ClassConst; //Silly copy paste solution end;
This is a sad state of affairs, but I do not see another option.
From Delphi 2010 onwards : use attributes
It is better to use attributes that you can access using RTTI :
The following code works:
program TestClassConst; {$APPTYPE CONSOLE} uses SysUtils, rtti; type NameAttribute = class(TCustomAttribute) private Fname: string; public constructor Create(const Name: string); property Name: string read Fname; end; [Name('Base class')] TParent = class const ClassConst = 'BASE CLASS'; private public class function Name: string; end; [Name('Child 1')] TChild1 = class(TParent) const ClassConst = 'CHILD 1'; end; [Name('Child 2')] TChild2 = class(TParent) const ClassConst = 'CHILD 2'; end; TParentClass = class of TParent; TChildClasses = array[0..1] of TParentClass; const ChildClasses: TChildClasses = (TChild1, TChild2); var i: integer; c: TParentClass; s: string; { TParent } class function TParent.Name: string; var Context: TRttiContext; ClassData: TRttiType; Attr: TCustomAttribute; begin Context:= TRttiContext.Create; ClassData:= Context.GetType(Self); try for Attr in ClassData.GetAttributes do begin if Attr is NameAttribute then Result:= NameAttribute(Attr).Name; end; finally ClassData.Free; end; end; { NameAttribute } constructor NameAttribute.Create(const Name: string); begin inherited Create; FName:= name; end; begin writeln; writeln('looping through class reference array'); for i := low(ChildClasses) to high(ChildClasses) do begin c := ChildClasses[i]; writeln(c.ClassName, ' -> ', c.Name); end; writeln; writeln('accessing classes directly'); writeln(TChild1.ClassName, ' -> ', TChild1.Name); writeln(TChild2.ClassName, ' -> ', TChild2.Name); readln; end.