Во-первых, извинения за длину этого поста. Если краткость - это душа остроумия, то это глупый вопрос.
Я думаю, что мой вопрос сводится к:
Каков наилучший способ переопределить константный массив в дочерних классах Delphi?
Справочная информация:
= - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = -
У меня есть константный массив, определенный в родительском классе, а также во многих дочерних классах.
Тип элементов массива всегда один и тот же, но количество элементов и точные данные отличаются от одного потомка к другому (я описываю таблицы базы данных из-за определенного элемента управления сеткой, который требует эти метаданные во время компиляции, но это не относится к делу).
У меня есть несколько функций, которые действуют на эти массивы. В качестве тривиального примера у меня может быть функция для возврата последнего элемента массива.
Если вы определите «GetLastElement» в родительском элементе, а затем вызовите эту унаследованную функцию от дочернего элемента, она все равно будет действовать на родительскую версию массива. Это не то, что я ожидал. Похоже, что дети должны вызывать унаследованную функцию в своей локальной версии массива.
В настоящее время я должен дублировать эти функции в каждом дочернем классе, что сводит с ума.
Я хочу, чтобы у меня была унаследованная функция , действующая на локальной версии моего константного массива. Каков наилучший способ сделать это? Я думал об определении функции в базовом классе, которая возвращает статический массив, а затем о переопределении этого для каждого дочернего элемента. Если бы я это сделал, я бы не работал с массивом, я бы работал с результатом функции.
Это решило бы проблему наследования, но оно вводит новую проблему в том, что Мне нужно будет определить новый тип для инкапсуляции массива и изменить мой (уже свернутый) элемент управления сеткой для работы этот тип.
Любые предложения приветствуются.
Ниже приведено упрощенное приложение, демонстрирующее, о чем я говорю:
В основной форме:
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.
В файле с именем 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.
В подразделении под названием 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.
В файле с именем 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.