我有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;
}
}
和一个带有main的类,主要工作中的以下代码
B b = new B();
b.first("unu")
.second();
b.bfirst();
但我想在同一个对象上链接两个类的方法。那可能吗?像
B b = new B();
b.first("unu")
.second()
.bfisrt();
答案 0 :(得分:4)
让我们分解吧。
public A first(String s){
list.add(s);
return this;
}
方法的返回类型为A
,因此调用new B().first("hi")
会返回A
类型的对象。因此,当我尝试编译时,我预计会出现错误incompatible types
。
您可以像标记空间的答案一样覆盖方法并执行相同操作,但返回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()'
答案 1 :(得分: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;
}
}
我没有对此进行测试(现在已经很晚了!)所以如果你需要的话,请仔细检查并使用它。
答案 2 :(得分:0)
您可以尝试投射
B b=new B();
((B)b.first("unu").second()).bfisrt();
希望这有帮助, Keshava。
答案 3 :(得分: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();