2009-07-07 138 views
5

有沒有辦法使用泛型說「此方法返回this」?有沒有辦法在Java中說「方法返回這個」?

當然,我想在子類中重寫此方法,所以聲明應該與@Override一起使用。

下面是一個例子:

class Base { 
    public Base copyTo (Base dest) { 
     ... copy all fields to dest ... 
     return this; 
    } 
} 
class X extends Base { 
    @Override 
    public X copyTo (X dest) { 
     super.copyTo (dest); 
     ... copy all fields to dest ... 
     return this; 
    } 
} 

public <T extends Base> T copyTo (Base dest)不會在所有的工作:我碰到一個「類型不匹配:不能從基地至T轉換」。如果我強制強制轉換,覆蓋失敗。

回答

4

不,沒有辦法表達這一點。只需聲明返回類的類型的方法即可。 Java有協變返回類型,所以你可以重寫一個方法來返回一個更具體的類型。

如果您想爲此添加一些標記,您可以隨時引入自己的註釋 - 但不要指望其他工具對其進行任何特別的注意。

編輯:從oxbow_lakes的答案確實會給大多數情況下工作的東西,但我相信有一些愚弄它的方法,讓你實際上處理不同的類型。 (無論如何,從實驗記憶來看)。請注意,這與Java枚舉的工作方式類似。

+0

除了我的(當然,馬丁·奧德斯基的)的方式;詳細上面 – 2009-07-07 08:32:26

+0

是的,雖然有沒有實現這種事情的方式沒有「這個」*實際*是這個。 – 2009-07-07 08:34:21

5

你可以做一些非常聰明的事情(類似於他們在Scala中用2.8 collection framework所做的)。聲明一些接口的方法應該返回「本身」(注:This是一個類型參數,而不是關鍵字)

public interface Addable<T, This extends Addable<T, This>> { 
    public This add(T t); 
} 

現在宣佈了一個間接層 - 一個「模板」類

public interface ListTemplate<A, This extends ListTemplate<A, This>> 
    extends Addable<A, This>{ 
} 

public interface List<A> extends ListTemplate<A, List<A>> { 
} 

隨後的List的實現必須從add方法返回一個List(我將讓你在IMPL填寫詳細信息)

public class ListImpl<A> implements List<A> { 

    public List<A> add(A a) { 
     return ... 
    } 
} 

類似地,你可以分解一個SetTemplate和一個Set來擴展Addable接口 - add方法將返回Set。很酷,嗯?

0

使用協變類型應該是簡單的:

abstract class Foo<T> { 

    Foo<T> get() { 
     return this.getClass().cast(this); 
    } 
} 

class Bar extends Foo { 

    @Override 
    Bar get() { 
     return (Bar) super.get(); 
    } 
}