2009-10-26 151 views
11

的返回類型,我有以下情況:Java泛型執行抽象方法

abstract class X { abstract X someMethod (...) {...} }. 

現在我想約束X的任何實施有它「的someMethod」方法返回一個特定的實現類型,而不僅僅是X :

class X1 extends X { X1 someMethod (...) {...} }. 
class X1 extends X { X someMethod (...) {...} }. //want this to be flagged as an error 
class X2 extends X { X1 someMethod (...) {...} }. //want this to be flagged as an error too 

使用Java泛型可以達到這個目的嗎?

編輯

好的。我只問了是/否問題並得到了「是」。我的錯。我真正感興趣的是「我如何撰寫聲明」。

回答

17

這也適用;

abstract class X<T> { 
    public abstract T yourMethod(); 
} 
class X1 extends X<X1> { 
    public X1 yourMethod() { 
     return this; 
    } 
} 
class X2 extends X<X2> { 
    public X2 yourMethod() { 
     return this; 
    } 
} 
+5

我認爲這是非常醜陋的代碼,但它也是我所知道的唯一解決方案,並且我自己使用它自己... +1 – rmeador 2009-10-26 22:56:54

+0

第二個想法......有人確實知道這是一個功能Jav – 2009-10-26 23:03:48

+0

... Java泛型的特徵,而不僅僅是它們構思/實現方式的危險副產品? – 2009-10-26 23:04:35

0

這應該只是罰款:

class X<T> { 
    abstract T someMethod(...); 
} 

class X1<T1> extends X 
    T1 someMethod(...) { 
    ... 
    } 
} 
4
abstract class X<I extends X<I>> { 
    protected X(Class<I> implClazz) { 
     if (!getClass().equals(implClazz)) { 
      throw new IllegalArgumentException(); 
     } 
    } 

    abstract I someMethod(); 
} 

理由:你不能指動態類型的類型限制,因此間接檢查在構造函數中。

+0

非常感謝,非常有幫助。 本來有投票權,但我得到一個「請登錄或註冊」的回覆。 – 2009-10-26 22:47:24

+0

您的理由爲什麼比約恩的解決方案仍然允許我寫 「class X2 extends X {X1 someMethod(){...}}」 – 2009-10-26 23:16:45

+0

準確地說。構造函數的唯一目的是防止這種情況。 – meriton 2009-10-26 23:47:07

2

這裏是一個可以讓你對this返回的參數類型的方法:

AbstractFoo<T extends AbstractFoo<T>> { 
    /** Subclasses must implement to return {@code this}. */ 
    protected abstract T getThis(); 

    /** Does something interesting and returns this Foo */ 
    public T inheritedThing { 
    /* blah di blah */ 
    return getThis(); 
    } 
}