我在许多 Java 代码符号中看到,在我们调用另一个方法之后,这里有一个示例。
Toast.makeText(text).setGravity(Gravity.TOP, 0, 0).setView(layout).show();
正如您在调用makeText
返回后看到的那样,我们调用setGravity
了到目前为止
我怎样才能用我自己的课程做到这一点?我需要做一些特别的事情吗?
我在许多 Java 代码符号中看到,在我们调用另一个方法之后,这里有一个示例。
Toast.makeText(text).setGravity(Gravity.TOP, 0, 0).setView(layout).show();
正如您在调用makeText
返回后看到的那样,我们调用setGravity
了到目前为止
我怎样才能用我自己的课程做到这一点?我需要做一些特别的事情吗?
这种模式被称为“Fluent Interfaces”(参见Wikipedia)
只是return this;
从方法而不是什么都不返回。
所以例如
public void makeText(String text) {
this.text = text;
}
会成为
public Toast makeText(String text) {
this.text = text;
return this;
}
class PersonMethodChaining {
private String name;
private int age;
// In addition to having the side-effect of setting the attributes in question,
// the setters return "this" (the current Person object) to allow for further chained method calls.
public PersonMethodChaining setName(String name) {
this.name = name;
return this;
}
public PersonMethodChaining setAge(int age) {
this.age = age;
return this;
}
public void introduce() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
}
// Usage:
public static void main(String[] args) {
PersonMethodChaining person = new PersonMethodChaining();
// Output: Hello, my name is Peter and I am 21 years old.
person.setName("Peter").setAge(21).introduce();
}
}
没有方法链
class Person {
private String name;
private int age;
// Per normal Java style, the setters return void.
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void introduce() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
}
// Usage:
public static void main(String[] args) {
Person person = new Person();
// Not using chaining; longer than the chained version above.
// Output: Hello, my name is Peter and I am 21 years old.
person.setName("Peter");
person.setAge(21);
person.introduce();
}
}
方法链接,也称为命名参数习语,是面向对象编程语言中调用多个方法调用的常用语法。每个方法都返回一个对象,允许在单个语句中将调用链接在一起。链接是语法糖,它消除了对中间变量的需求。方法链也被称为火车残骸,因为即使在方法之间经常添加换行符,随着更多方法链接在一起,同一行中一个接一个地出现的方法数量也会增加。
类似的语法是方法级联,在方法调用之后,表达式计算为当前对象,而不是方法的返回值。级联可以使用方法链来实现,方法是让方法返回当前对象本身(this)。级联是流畅接口中的一项关键技术,并且由于链式在面向对象语言中广泛实现,而级联不是,这种形式的“通过返回 this 进行级联”通常简称为“链式”。链接和级联都来自 Smalltalk 语言。
从你的例子:
Toast.makeText(text).setGravity(Gravity.TOP, 0, 0).setView(layout).show();
链中的每个方法都必须返回一个类或一个接口。链中的下一个方法必须是返回类的一部分。
我们从吐司开始。在 Toast 类中定义为静态方法的 makeText 方法必须返回一个类或一个接口。在这里,它返回 Gravity 类的一个实例。
在 Gravity 类中定义的方法 setGravity 返回 View 类的实例,
在 View 类中定义的方法 setView 返回 JPanel 类的实例。
这个链可以一步一步写出来。
Gravity gravity = Toast.makeText(text);
View view = gravity.setGravity(Gravity.TOP, 0, 0);
JPanel panel = view.setView(layout);
panel.show();
将链写成链会从源代码中删除所有中间实例变量。
在 google 上搜索 builder pattern 或 fluent interface 以获得更多详细信息。
在大多数情况下,在方法末尾返回“this”可以解决问题。
添加返回这个;肯定会有助于链接此类,但对于子类则失败。
如果您还希望将链接行为继承到子类,请更改您的类签名,如下所示:
类超类 < 子类扩展超类 >{}
这样所有子类都将继承方法链。
例子:
public class SuperClass<SubClass extends SuperClass> {
public SubClass testMethod(){
return (SubClass)this;
}
public static void main(String[] args) {
SuperClass<SuperClass> superClass = new SuperClass<SuperClass>();
superClass.testMethod().testMethod().testMethod();
System.out.println(superClass.toString());
}
}
或者您可以使用Diezel,它会根据您的 fluent API 的正则表达式生成您需要的所有接口。