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

Java 创建根据调用对象的实现返回不同对象的抽象方法,java,Java,我有五个从超类扩展而来的类,例如,我将其称为AbstractEntity类。每个实体都有一组entityData: @Entity @Table(name = "entity1") class Entity1 extends AbstractEntity{ @OneToMany(mappedBy = "Entity1") private Set<EntityData1> data; ... public Set<EntityData1> getData()

我有五个从超类扩展而来的类,例如,我将其称为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; }
}
Entity和EntityData在DB中都是独立的表,也就是说,我们有5个表用于Entity1到Entity5,5个表用于EntityData1到EntityData5

我们需要的是编写一个方法的能力,该方法可以获取任何实体对象并从中调用getData()方法,然后返回正确的EntityData对象。也就是说,如果从Entity2调用getData(),则会得到EntityData2。 现在,如果有人想要创建一个方法来循环遍历entityData对象来查找某些内容,那么他必须用非常相似的代码编写五个单独的方法

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

abstract class AbstractEntity{
  ...
    public abstract <T> Set<T> getData();
}
抽象类AbstractEntity{
...
公共抽象集getData();
}
然后访问entityData对象,例如:

public static <T> T findPropertyByAlias(T entity){ 
    for (T entityData : entity.getData()) {
        do something
    }
    return entityData for appropriate Entity object.
}
公共静态T findPropertyByAlias(T实体){
对于(T entityData:entity.getData()){
做点什么
}
返回相应实体对象的entityData。
}
但这显然不起作用。 有没有一种实用的方法可以将getData()方法放入抽象类中,但使其返回适当的entityData对象?

考虑您的示例(在注释中):

最简单的方法之一:

  • 创建一个名为“数据”的接口
  • 让您的所有类(如WolfData和SheepData)实现此接口
  • 将returnType设置为Data

  • 这样,每个数据实现(包括WolfData和SheepData)都可以作为返回值。

    您所使用的泛型方法是正确的。然而,它需要一些修改

    abstract class AbstractEntity <T extends AbstractData>{
        public abstract Set<T> getData();
    }
    
    抽象类AbstractEntity{
    公共抽象集getData();
    }
    
    然后声明实体实现,如下所示:

    @Entity
    @Table(name = "entity1")
    class Entity1 extends AbstractEntity<EntityData1>{
      @OneToMany(mappedBy = "Entity1")
      private Set<EntityData1> data;
    
      public Set<EntityData1> getData()
      { return data; }
    }   
    
    @实体
    @表(name=“entity1”)
    类Entity1扩展了AbstractEntity{
    @OneToMany(mappedBy=“Entity1”)
    私有集数据;
    公共集getData()
    {返回数据;}
    }   
    

    公共静态T findPropertyByAlias(T实体){
    对于(T entityData:entity.getData()){
    做点什么
    }
    返回相应实体对象的entityData。
    }   
    
    抽象实体
    引入一个通用参数:

    interface AbstractData {}
    abstract class AbstractEntity<DATA extends AbstractData> {
        public abstract Set<DATA> 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();
    }
    
    公共静态集合findPropertyByAlias(T实体){
    对于(D数据:entity.getData()){…}
    返回entity.getData();
    }
    

    我正在返回一个
    集合
    ,但您可能需要集合中的一个元素。如果是这样,请将返回类型更改为
    D
    ,并选择需要返回的元素。

    您是指不同类型的对象吗?我的意思是,如果我从Wolf类型的对象调用getData,我将获得WolfData,但如果我从Sheep类型的对象调用它,我会得到SheepData。返回
    Set@Turing85他说的不是实体本身,而是一个我不知道你会写的成员。我现在就去试试。谢谢。我投了反对票,因为
    AbstractData
    没有
    getData
    方法看起来很有效!只有我把findPropertyByAlias()改成这样:public static T findPropertyByAlias(AbstractEntity)非常感谢。你帮了很多忙。我的Java技能也获得+1000XP:)
    class Entity1 extends AbstractEntity<EntityData1> {
        ...
        @Override
        public Set<EntityData1> getData() { ... }
    }
    
    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();
    }