2014-07-25 120 views
4

我有2類:鏈接方式,方法

public class A { 
    private final List<String> list; 

    public A() {   
     list = new ArrayList<String>(); 
    } 

    public A first(String s) {  
     list.add(s); 
     return this; 
    } 

    public A second() { 
     System.out.println(list); 
     return this; 
    } 
} 

public class B extends A { 
    public B bfisrt() { 
     System.out.println("asd"); 
     return this; 
    } 
} 

,並在主要的工作與主,下面的代碼類

B b = new B(); 

b.first("unu") 
    .second(); 

b.bfirst(); 

,但我想要在同一個對象上鍊接兩個類的方法。這是可行的嗎?像

B b = new B(); 

b.first("unu") 
    .second() 
    .bfisrt(); 
+1

也嘗試一下,看看它有可能.. – nafas

回答

1

我這麼認爲。您必須重寫B中A的方法才能使其工作。

public class B extends A{ 

    public B bfisrt(){ 
     System.out.println("asd"); 
     return this; 
    } 
    public B first(String s){ 
     super.first(s);  
     return this; 
    } 
    public B second(){ 
     super.second(); 
     return this; 
    } 
} 

我還沒有測試過這個(它已經很晚了!),所以仔細檢查一下,如果你必須的話。

+0

謝謝。 ,它與重寫一起工作。在這個項目中,我正在處理超類,有很多方法返回這個,並且沒有用。我會堅持使用 – Eli

0

您可以嘗試鑄造

B b=new B(); ((B)b.first("unu").second()).bfisrt();

希望這有助於 Keshava。

4

讓我們來分解它。

public A first(String s){  
    list.add(s); 
    return this; 
} 

方法的返回類型是A,因此調用new B().first("hi")返回A類型的對象。所以當我試圖編譯時,我預計會有一個錯誤,說incompatible types

你可以像markspace答案,覆蓋的方法,做相同的,但返回B

public B first(String s){ 
    super.first(s);  
    return this; 
} 

甚至

public B first(String s) { 
    return (B)super.first(s);  
} 

Kesheva的方法需要您手動轉換返回類型時是A,但你知道這是一個B

B b = new B(); 
((B)b.first("unu").second()).bfisrt(); 

但是,尤其是對於需要多次投射的較長鏈,這是高度代碼混亂的。

這是另一個可能適合您需要的解決方案。

public abstract class A { 
    public <Unknown extends A> Unknown first(String s) { 
     System.out.println("in here"); 
     return (Unknown)this; 
    } 
} 

public class B extends A { } 

public static void main(String[] args) { 
    //compiles without overriding the method or manually casting. 
    B b = new B().first("hi").first("hello"); 
} 

this StackOverflow thread您可以閱讀爲什麼這個作品。

編輯:爲newacct指出的那樣,它可以是偏於安全,但只有如果你不使用生成器模式,如果你不看你分配給什麼。考慮下面兩段代碼:

B b = new B().first("hi").first("hello"); 
// above compiles and works. You assign 'B b' to a `new B()` 

class C extends A { } 
C c = new B().first("hi"); 
// ClassCastException, but you can see that instantly. 'C c' gets assigned to 'new B()' 
+0

+1的代碼,用於使用泛型的'first()'方法實現,這是完美的解決方案。 –

+0

答案的答案。根據您的解決方案,我已經更改了A中的方法。但是我仍然無法將B類的方法鏈接到b.first(「s」)。second()。在eclipse中輸入最後一點之後,方法的默認提議甚至不顯示類B的方法。 – Eli

+0

嗯,你是對的。它與編譯器推斷類型的方式有關。這有效('B b = new B()。classAMethod1()。classAMethod2(); b.classBMethod()'),但這不幸的是:'B b = new B()。classAMethod1()。 classAMethod2()。classBMethod();' – stealthjong

0

找到解決方案:

public abstract class X<T extends X<T>> { 

    public abstract T self(); 

    public T xFirst(){ 
     System.out.println("xxx"); 
     return self(); 
    } 
} 



public class Y extends X<Y>{  

    public Y yfirst(){ 
     System.out.println("yyy"); 
     return self(); 
    } 

    @Override 
    public Y self() {  
     return this; 
    } 
    } 

,並在主鏈可以用忽略繼承

new Y().xFirst().yfirst().xFirst().yfirst();