2008-09-30 53 views
4

我想要一個實現接口的類,它將特定的子類指定爲參數。通用類型參數指定擴展類嗎?

public abstract Task implements TaskStatus<Task> { 
    TaskStatus<T> listener; 

    protected complete() { 
     // ugly, unsafe cast 
     callback.complete((T) this); 
    } 
} 

public interface TaskStatus<T> { 
    public void complete(T task); 
} 

但不是隻是任務,或者,我想保證所使用的type-arg是擴展這個類的特定類。

所以我想出最好的是:

public abstract Task<T extends Task> implements TaskStatus<T> { 
} 

你會延長,通過寫:

public class MyTask extends Task<MyTask> { 
} 

但是,這也將是有效的:

public class MyTask extends Task<SomeOtherTask> { 
} 

而回調的調用將爆炸與ClassCastException。那麼,這種做法是錯誤的嗎?或者有沒有正確的方法可以做到這一點,我不知何故錯過了?

回答

2

目前還不清楚你在Task裏面想要做什麼。但是,如果你定義泛型類Task<T>如下:

class Task<T extends Task<T>> { ... } 

以下兩個是可能的:

class MyTask extends Task<MyTask> { ... } 
class YourTask extends Task<MyTask> { ... } 

但禁止下列內容:

class MyTask extends Task<String> { ... } 

Task上述定義使用F-bound多態,這是一個相當先進的特性。您可以查看研究論文「F-bounded polymorphism for object-oriented programming」以獲取更多信息。

0

我在理解你想要通過它完成什麼時遇到了一些麻煩。你能否提供更多的細節?

我讀到的代碼說你有這些任務將被分類,任務完成後,正在執行的線程將在任務上調用complete()。此時,您想調用回調並將其傳遞給子類對象。我認爲這是問題。你試圖把潛在的子類的知識放到你的抽象類中,這是一個不容否認的問題。

這也引發了一個問題,如果你可以進行這個調用,那麼與子類不同的子類的回調是什麼?

1

我建議添加一個getThis應該返回這適當類型。當然,一個子控件可能會行爲不端,但事實並非如此。你避免的是演員和ClassCastException的可能性。

public abstract class Task<THIS extends Task<THIS>> { 
    private TaskStatus<THIS> callback; 

    public void setCallback(TaskStatus<THIS> callback) { 
     this.callback = callback==null ? NullCallback.INSTANCE : callback; 
    } 

    protected void complete() { 
     // ugly, unsafe cast 
     callback.complete(getThis()); 
    } 

    protected abstract THIS getThis(); 
} 

public interface TaskStatus<T/* extends Task<T>*/> { 
    void complete(T task); 
} 

public class MyTask extends Task<MyTask> { 
    @Override protected MyTask getThis() { 
     return this; 
    } 
} 

這個問題經常會出現在構建器中。

+0

的'擴展任務'是沒有意義的,應該在這裏移除 – newacct 2013-07-28 10:24:52

0

我真的只能看到這個工作,如果你在構造函數強制類型arg。通過。內省和Class.getSuperType()你可以檢查類型參數,並驗證類型arg是否匹配這個類。沿線的

財產以後:

assert getClass() == ((ParameterizedType) getSuperType()).getTypeArguments()[0]; 

(這是從上了我的頭,檢查的JavaDocs驗證)。

我不確定在你的代碼中哪裏創建了回調。您已經省略了它在頂部的聲明。

不同的路線是去除不安全的演員,如atm。我看不到完整的流程來發現爲什麼你需要不安全的演員。