抽象类的序列化,包含具有不同子类对象类型的列表。

huangapple go评论88阅读模式
英文:

Serialization of an abstract class with a list containing mixed subclassed object types

问题

我有一个抽象类,定义了图形中要绘制的分数项的结构。有多个变体的分数项。它们都有相同的实例变量,但每个变体都有自己的绘制实现,这些实现非常大且复杂。这些绘制实现主要包括三角计算,并且几乎不共享任何代码。

为了保持代码的可读性,我想为每个变体使用一个子类。在子类中,我将定义绘制方法的实现。下面是简化的示例:

abstract class ScoreItem {
  int score;
  Color color;
  ...
  
  abstract void draw();
  
  public class RadarItem extends ScoreItem {
    @Override
    public void draw() {
      // 雷达的实现
      ...
    }
  }
  
  public class LineItem extends ScoreItem {
    @Override
    public void draw() {
      // 线条的实现
      ...
    }
  }
  // 其他子类
}

现在,我想在一个名为Graphic的类中拥有一个ScoreItems列表。该列表可以包含抽象ScoreItem的不同变体,该类必须循环遍历ScoreItems以绘制它们,如下所示:

public class Graphic {
  ...
  
  public void generate() {
    List<ScoreItem> scoreItems = ...;
    
    for (ScoreItem scoreItem : scoreItems) { scoreItem.draw(); }
  }
}

现在这应该可以工作;我在一个简单的测试项目中测试过。然而,我遇到问题的地方在于,Graphic类必须被序列化,而且我在反序列化方面遇到了麻烦。这不起作用(java.lang.RuntimeException:“找不到类”字段的抽象类)。我认为GSON不能对抽象类进行反序列化。当我将ScoreItem类更改为普通类时,显然GSON的反序列化可以工作,但是这样我就无法在子类上使用draw()方法。

我希望我已经足够清楚和简洁地描述了这个问题。也许在列表中使用不同的对象类型并不是一个好的做法。对于此问题,任何解决方案或建议都将非常赞赏。

英文:

I have an abstract class that defines the structure of a scoreitem to be drawn in a graphic. There are multiple variants of the score items. They all have the same instance variables, but each has its own drawing implementation which is quite large and complex. These drawing implementations consist mainly of goniometric calculations and do hardly share any code.

In order to keep the code readable, I want to use a subclass for each variant. In the subclass I will define the drawing method implementation. See simplified example below.

abstract class ScoreItem {
  int score;
  Color color;
  ...
  
  abstract void draw();

  public class RadarItem extends ScoreItem {
    @Override
    public void draw() {
      // RADAR IMPLEMENTATION
      ...
    }
  }

  public class LineItem extends ScoreItem {
    @Override
    public void draw() {
      // LINE IMPLEMENTATION
      ...
    }
  }
etc.
}

Now, I want to use a Graphic class in which I have a list of ScoreItems. The list can contain different variants of the abstract ScoreItem, and the class must loop over the ScoreItems in order to draw them, like below:

public class Graphic {
  ...

  public void generate() {
    List&lt;ScoreItem&gt; scoreItems = ...;

    for (ScoreItem scoreItem : scoreItems) { scoreItem.draw(); }
  }
}

Now this should work; I tested it in a simple test project. However, where I'm running into problems; the Graphic class must be serialized and I'm getting into trouble with the deserialization. This doesn't work (java.lang.RuntimeException: "class" field not found for abstract class). I assume GSON cannot deserialize into the abstract class. When I change the ScoreItem class into a regular class, obviously GSON deserialization works, but then I can't use the draw() method on the subclasses.

I hope I have described the problem adequately and consisely enough. Maybe it's just not good pracice to use a List with different object types. Any solutions or recommendations are greatly appreciated.

答案1

得分: 1

随着答案将我引导到正确的方向,解决方案是使用一个 GSON 接口适配器(更改为抽象适配器)。

如此所述

英文:

With the answers nudging me in the right direction, the solution was to use an GSON Interface Adapter (changed to an Abstract Adapter).

As described here.

huangapple
  • 本文由 发表于 2020年8月19日 22:09:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63488868.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定