2014-07-25 74 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();