Firstly, an apology for the length of this post. If brevity is the soul of wit, then this is a witless question.
I think my question boils down to:
What is the best way to override a constant array in Delphi child classes?
Background:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
I have a constant array that is defined in a parent class, and also in lot of child classes. The type of the array elements is always the same, but the number of elements and the exact data differs from one child to the next (I am describing database tables, because of a specific grid control that requires that meta-data at compile time, but that's beside the point).
I have several functions that act on these arrays. As a trivial example, I might have a function to return the last element of the array.
If you define a "GetLastElement" in the parent, then call that inherited function from a child, it will still act on the parents version of the array. This is not what I expected. It seems like the children should call the inherited function on their own local version of the array.
Currently I have to duplicate those functions across each child class, which is maddening.
I want to be able to have an inherited function act on the local version of my constant array. What is the best way to do that? I have thought about defining a function in the base class that returns a static array, and then overriding that for each child. If I did that, then I would not be acting on an array, I'd be acting on a function result.
That would solve the inheritance problem, but it introduces a new problem in that I'd have to define a new type to encapsulate the array, and modify my (already convoluted) grid control to work with that type.
Any suggestions are welcome.
Below is a simplified application that demonstrates what I'm talking about:
In a Main form:
implementation
{$R *.dfm}
uses
ParentClass, Descendant1, Descendant2;
procedure TfrmMain.btnTestClick(Sender: TObject);
var
d1, d2: TParentClass;
begin
d1 := TDescendant1.Create;
d2 := TDescendant2.Create;
//as it stands, this will return "E", then "A", which is good.
//but if you move the LastElementOfArray function to the ParentClass,
//then it will return "E", "E", ignoring the version of the array
//defined inside TDescendant2.
ShowMessage('d1=' + d1.LastElementOfArray);
ShowMessage('d2=' + d2.LastElementOfArray);
end;
end.
In a file called ParentClass.pas:
unit ParentClass;
interface
type
TParentClass = class
public
function LastElementOfArray: string; virtual; abstract;
end;
const
c_MyConstantArray: array[1..5] of string = ('A','B','C','D','E');
implementation
end.
In a unit called Descendant1.pas
//here, we will just take whatever array we got from the parent
unit Descendant1;
interface
uses
ParentClass;
type
TDescendant1 = class(TParentClass)
public
function LastElementOfArray: string; override;
end;
implementation
{ TDescendant1 }
function TDescendant1.LastElementOfArray: string;
begin
Result := c_MyConstantArray[High(c_MyConstantArray)];
end;
end.
In a file called Descendant2.pas
//override with a new version of the constant array (same length)
unit Descendant2;
interface
uses
ParentClass;
type
TDescendant2 = class(TParentClass)
public
function LastElementOfArray: string; override;
end;
const
c_MyConstantArray: array[1..5] of string = ('E','D','C','B','A');
implementation
{ TDescendant2 }
function TDescendant2.LastElementOfArray: string;
begin
//I hate defining this locally, but if I move it to ParentClass,
//then it will act on the ParentClass version of the array, which
//is **NOT** what I want
Result := c_MyConstantArray[High(c_MyConstantArray)];
end;
end.