Десериализация абстрактного класса? Приветствую.
Имеется такой набор классов 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;

21 Авг 2019 в 07:04
210 +1
0
Ответы
1

Для сохранения значения 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.

20 Апр 2024 в 13:08
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир