Десериализация абстрактного класса? Приветствую. Имеется такой набор классов Delphi XE2:TBaseAbstractClass = class abstract name : string; end; TDerivedClassStr = class(TBaseAbstractClass) value : string; end; TDerivedClassFloat = class(TBaseAbstractClass) value : float; end; TMyObject = class objs : array of TBaseAbstractClass; end; Есть JSON:{ [ {"name" : "name1", "value" : "value1"}, {"name" : "name1", "value" : "value2"} ] } Его можно десериализировать как TMyObject, но тогда теряются value, а привидение типов вызывает ошибку (что мне совсем не очевидно). Десериализация производится библиотекой superobject. Есть ли способ сохранить значение value, но так, чтобы не создавать:TMyObject = class objs : array of TDerivedClassStr; end;
Для сохранения значения value при десериализации JSON в абстрактный класс TBaseAbstractClass можно воспользоваться полиморфизмом и создать фабрику объектов, которая будет создавать экземпляры подходящего класса на основе данных из JSON.
Ниже приведен пример кода, демонстрирующий этот подход:
type TBaseAbstractClass = class abstract name: string; constructor Create; virtual; abstract; end; TDerivedClassStr = class(TBaseAbstractClass) value: string; constructor Create; override; end; TDerivedClassFloat = class(TBaseAbstractClass) value: Float; constructor Create; override; end; function CreateObjectFromJSON(jsonData: ISuperObject): TBaseAbstractClass; begin if jsonData.Get('value').DataType = stString then begin Result := TDerivedClassStr.Create; TDerivedClassStr(Result).value := jsonData.S['value']; end else if jsonData.Get('value').DataType = stDouble then begin Result := TDerivedClassFloat.Create; TDerivedClassFloat(Result).value := jsonData.F['value']; end else Result := nil; end; procedure DeserializeJSON(jsonData: ISuperObject; var myObject: TMyObject); var i: Integer; begin SetLength(myObject.objs, jsonData.Length); for i := 0 to jsonData.Length - 1 do begin myObject.objs[i] := CreateObjectFromJSON(jsonData[i]) as TBaseAbstractClass; end; end;
Таким образом, при десериализации JSON вы можете использовать фабрику объектов CreateObjectFromJSON, которая будет создавать экземпляры подходящего класса на основе данных из JSON, и сохранять значение value в соответствующем поле объекта-наследника TBaseAbstractClass.
Для сохранения значения value при десериализации JSON в абстрактный класс TBaseAbstractClass можно воспользоваться полиморфизмом и создать фабрику объектов, которая будет создавать экземпляры подходящего класса на основе данных из JSON.
Ниже приведен пример кода, демонстрирующий этот подход:
typeTBaseAbstractClass = class abstract
name: string;
constructor Create; virtual; abstract;
end;
TDerivedClassStr = class(TBaseAbstractClass)
value: string;
constructor Create; override;
end;
TDerivedClassFloat = class(TBaseAbstractClass)
value: Float;
constructor Create; override;
end;
function CreateObjectFromJSON(jsonData: ISuperObject): TBaseAbstractClass;
begin
if jsonData.Get('value').DataType = stString then
begin
Result := TDerivedClassStr.Create;
TDerivedClassStr(Result).value := jsonData.S['value'];
end
else if jsonData.Get('value').DataType = stDouble then
begin
Result := TDerivedClassFloat.Create;
TDerivedClassFloat(Result).value := jsonData.F['value'];
end
else
Result := nil;
end;
procedure DeserializeJSON(jsonData: ISuperObject; var myObject: TMyObject);
var
i: Integer;
begin
SetLength(myObject.objs, jsonData.Length);
for i := 0 to jsonData.Length - 1 do
begin
myObject.objs[i] := CreateObjectFromJSON(jsonData[i]) as TBaseAbstractClass;
end;
end;
Таким образом, при десериализации JSON вы можете использовать фабрику объектов CreateObjectFromJSON, которая будет создавать экземпляры подходящего класса на основе данных из JSON, и сохранять значение value в соответствующем поле объекта-наследника TBaseAbstractClass.