2016-02-29 63 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

謝謝範例 –