【问题标题】:Generic interface for multiple sub types of an abstract class and dynamic casting抽象类的多个子类型和动态转换的通用接口
【发布时间】:2021-05-17 06:52:27
【问题描述】:

我有一个场景可以简化如下:

  • 我有一个名为 AbstractField 的抽象类
  • 可以从这个类扩展许多类:CurrencyFieldDecimalField等。
  • 现在我有一个通用接口 FieldDBStore 来创建或更新数据库中的字段详细信息。
  • 我想为每种类型的字段实现上述接口(只要存储方式不同)。

这里是一些代码示例:

对于抽象域

/* AbstractField */
public abstract class AbstractField {
    //private members
    // builder
}

对于货币字段

public class CurrencyField extends AbstractField {
    //private members
    // builder that is extended from parent class's builder
}

对于 FieldDBStore

interface FieldDBStore<T extends AbstractField> {
    
    void createField(T field, String tableName, String columnName);
    
    void updateField(T field);
}

CurrencyFieldDBStore

public class CurrencyFieldDBStore implements FieldDBStore<CurrencyField> {
    @Override
    public void createField(CurrencyField field, String tableName, String columnName) {
        // Some operations
        
    }

    @Override
    public void updateField(CurrencyField field) {
        // Some operations
        
    }
}

现在的问题是:每当客户端尝试发送要创建/更新的字段时,它都不知道字段类型。因此,它将将该字段作为超类型(AbstractField)发送。这导致在 eclipse 中可见以下错误

public AbstractField createAbstractField(AbstractField field, Long userId) { 
    //FieldType is an enum that can return appropriate DBStore implementation as per the field type
    FieldType type = field.getFieldType();
    String tableName = "SomeTableName";
    String columnName = "SomeColumnName";
    type.getFieldDBStore().createField(field, tableName, columnName);

在上面的代码中,最后一行抛出了这个错误

方法 createField(capture#2-of ? extends AbstractField, String, String) 在类型 FieldDBStore 不适用于参数(AbstractField、String、String)

我尝试实现一个抽象字段数据库存储,然后对其进行扩展,但这并没有解决问题。任何建议将不胜感激

【问题讨论】:

  • type.getFieldDBStore().createField 尝试调用具有特定类型的方法。例如CurrencyField,但AbstractField 不是CurrencyField。那将是kontravariant。因此,在这种情况下,您需要使用上限。例如void &lt;T extends AbstractField&gt; void createAbstractField(T field, Long userId) { } 说除了作为 AbstractField 子类型的每个类型
  • @DanielWosch 谢谢!按照您所说的更改调用者方法可以解决问题。
  • 不客气。将我的评论发布为答案,以便您将其标记为已接受的答案。

标签: java oop generics


【解决方案1】:

type.getFieldDBStore().createField() 尝试调用具有特定类型的方法。例如CurrencyField,但AbstractField不是CurrencyField

这应该是逆变的。

因此,在这种情况下您需要使用上限。例如

void &lt;T extends AbstractField&gt; void createAbstractField(T field, Long userId) { //impl... }

说:这个方法除了AbstractField的子类型,包括AbstractField

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 2010-11-08
    • 2017-02-19
    • 2014-04-12
    相关资源
    最近更新 更多