2016-02-29 64 views
2

我有一个抽象类,有一个字段的类型可以在其子类之间变化。例如:如何从抽象类实现泛型字段?

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

在我的实现中,baz可能是一个Int或Float。例如:

public class ModelFoo { 
    protected Int baz; 
} 

public class Modelbar { 
    protected Float baz; 
} 

首先,让我问一下,在Java中这是否是有效/可接受的设计模式?我选择了这种模式,因为我想抽象出共享方法中大部分乏味的样板。

取决于我如何实现它,我得到这个错误的变化:

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

这使我相信我做错了什么。

我发布的例子与我的实际代码相比有点微不足道,在这个代码中,这个泛型被嵌入在一个嵌套散列表中。我试图决定我在做什么是一个聪明的设计在Java或不太投入之前。

我试过寻找这个,但可能没有正确阐明术语。

谢谢。

+2

一目了然,这应该是'类ABCModel ','类ModelFoo扩展ABCModel ','类ModelBar扩展ABCModel '。 –

+0

所以你说的是“”会在指定T的地方被覆盖? IE的所有引用将成为Ints或浮动,例如? –

+0

大约。这比中等复杂,但是,是的,这是主意。 –

回答

3

你是什么问的是仿制药的基本用法:

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(); 
+0

谢谢你举例 –

+0

你可以在调用getters时只依靠自动装箱/取消装箱 – flakes

+1

@flkes在生产中得到一些NullPointerExceptions后你不会那么肯定;) – AdamSkywalker

1

字段不能在Java中重写。但是,您可以使用泛型方法。

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

然后

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

所以我的受保护的变量根本不被继承? –

+0

更正,不能被覆盖 –

+0

它们不能被覆盖,但它们当然可以被继承并且通用。 –

1

这是一个公认的模式,但你应该更具体谈谈您的仿制药:

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

    public T getBaz() { 
     return baz; 
    } 
} 

那之后,你可以扩展你的模型:

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

谢谢范例 –