简体   繁体   English

如何实现抽象类的泛型字段?

[英]How to implement generic fields from abstract class?

I have an abstract class that has one field whose type can vary between its subclassses. 我有一个具有一个字段的抽象类,该字段的类型在其子类之间可能有所不同。 For example: 例如:

public abstract class ABCModel {
    protected String foo;
    protected String bar;
    protected ? baz;
}

In my implementations, baz may be an Int or a Float. 在我的实现中, baz可以是Int或Float。 For example: 例如:

public class ModelFoo {
     protected Int baz;
}

public class Modelbar {
     protected Float baz;
}  

First, let me ask if this is a valid/accepted design pattern in Java? 首先,请问这在Java中是否是有效/可接受的设计模式? I've chosen this pattern because I want to abstract-away most of the tedious boilerplate in the shared methods. 我之所以选择这种模式,是因为我想从共享方法中抽象出大部分繁琐的样板。

Depending on how I implement it, I get variations of this error: 根据我的实现方式,我会得到此错误的变种:

incompatible types: CAP#1 cannot be converted to BidAsk
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?

This leads me to believe I'm doing something wrong. 这使我相信我做错了什么。

The example I posted is a bit trivial compared to my actual code, in which this generic is buried in a nested hashtable. 与我的实际代码相比,我发布的示例有点琐碎,在该示例中,该泛型被埋在嵌套的哈希表中。 I'm trying to decide if what I'm doing is a smart design in Java or not before getting too invested. 在尝试投入太多资金之前,我试图确定我正在做的是在Java中进行智能设计。

I've tried searching for this, but probably am not articulating the terminology correctly. 我尝试搜索此内容,但可能未正确表达该术语。

Thanks. 谢谢。

What you are asking is the basic usage of generics: 您要问的是泛型的基本用法:

public abstract class ABCModel<T> {
    private T baz;

    public T getBaz() { return baz; }

    public void setBaz(T baz) { this.baz = baz; }
}

public class IntModel extends ABCModel<Integer> { // baz is of type Integer   
}

public class FloatModel extends ABCModel<Float> { // baz is of type Float   
}

IntModel m1 = new IntModel();
Integer i = m1.getBaz();

FloatModel m2 = new FloatModel();
Float f = m2.getBaz();

Fields cannot be overridden in Java. 在Java中不能覆盖字段。 You can however use methods with generics. 但是,您可以将方法与泛型一起使用。

public abstract class ABCModel<T> {
    public abstract T getBaz();
}

Then 然后

public class ModelFoo extends ABCModel<Integer> {
    public Integer getBaz() {
        ...
    }
}

This is an accepted pattern, but you should be more specific about your generics : 这是一种可接受的模式,但是您应该更详细地了解泛型:

public abstract class ABCModel<T extends Number> {
    protected String foo;
    protected String bar;
    protected T baz;

    public T getBaz() {
      return baz;
    }
}

After that you can extend your model : 之后,您可以扩展模型:

public class ModelFoo extends ABCModel<Integer> {
     // No need to specify again baz.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM