创建抽象方法,根据调用的实现来返回不同的对象

时间:2018-01-11 10:39:44

标签: java

我有五个从超类扩展的类,我将其称为AbstractEntity类。每个实体都有一组entityData:

@Entity
@Table(name = "entity1")
class Entity1 extends AbstractEntity{
  @OneToMany(mappedBy = "Entity1")
  private Set<EntityData1> data;
  ...
  public Set<EntityData1> getData()
  { return data; }
}

@Entity
@Table(name = "entity2")
class Entity2 extends AbstractEntity{
  @OneToMany(mappedBy = "Entity2")
  private Set<EntityData2> data;
  ...
    public Set<EntityData2> getData()
    { return data; }
}

每个EntityData依次从AbstractData类扩展。

@Entity
@Table(name = "entity_data1")
class EntityData1 extends AbstractData{
    @ManyToOne(...)
    @JoinColumn(name = "entity1_ID")
    private Entity1 entity1;
    ...
}

Entity和EntityData都是DB中的单独表,即Entity1到Entity5有5个表,EntityData1到EntityData5有5个表。

我们需要的是编写单个方法的能力,该方法可以接受任何Entity对象并从中调用getData()方法并获得正确的EntityData对象。也就是说,如果从Entity2调用getData(),您将获得EntityData2。 现在,如果有人想创建循环通过entityData对象来查找内容的方法,那么他必须编写五个单独的方法和非常相似的代码。

我试图将getData()方法放在AbstractEntity类中,如下所示:

abstract class AbstractEntity{
  ...
    public abstract <T> Set<T> getData();
}

然后访问entityData对象,例如:

public static <T> T findPropertyByAlias(T entity){ 
    for (T entityData : entity.getData()) {
        do something
    }
    return entityData for appropriate Entity object.
}

但这显然不起作用。 有没有一种实用的方法将getData()方法转换为抽象类,但是要使它返回适当的entityData对象?

3 个答案:

答案 0 :(得分:1)

您所做的泛型方法是正确的。但是,它需要一些修改。

@Entity
@Table(name = "entity1")
class Entity1 extends AbstractEntity<EntityData1>{
  @OneToMany(mappedBy = "Entity1")
  private Set<EntityData1> data;

  public Set<EntityData1> getData()
  { return data; }
}   

然后按如下方式声明实体实现:

public static <T extends AbstractData> T findPropertyByAlias(T entity){ 
    for (T entityData : entity.getData()) {
        do something
    }
    return entityData for appropriate Entity object.
}   
{{1}}

答案 1 :(得分:1)

AbstractEntity

引入通用参数
interface AbstractData {}
abstract class AbstractEntity<DATA extends AbstractData> {
    public abstract Set<DATA> getData();
}

每个Entity决定使用哪个AbstractData实现:

class Entity1 extends AbstractEntity<EntityData1> {
    ...
    @Override
    public Set<EntityData1> getData() { ... }
}

每个EntityData都是AbstractData

class EntityData1 implements AbstractData {}

该方法可能如下所示:

public static <D extends AbstractData, T extends AbstractEntity<D>> Set<D> findPropertyByAlias(T entity) {
    for (D data : entity.getData()) { ... }
    return entity.getData();
}

我正在返回Set<D>,但您可能想要该集合的元素。如果是这样,请将返回类型更改为D并选择要返回的所需元素。

答案 2 :(得分:0)

考虑你的例子(在评论中):

(其中一种)最简单的方法:

  1. 创建名为“数据”
  2. 的界面
  3. 让你的所有课程,比如WolfData和SheepData实现这个界面
  4. 将returnType设置为Data。
  5. 这样,数据的每个实现(包括WolfData和SheepData)都被允许作为返回值。