代码之家  ›  专栏  ›  技术社区  ›  Pentium10

如何在Java中进行方法链?o.m1().m2().m3().m4()。

  •  35
  • Pentium10  · 技术社区  · 14 年前

    我在许多Java代码符号中看到,在我们调用另一个方法之后,这里是一个例子。

    Toast.makeText(text).setGravity(Gravity.TOP, 0, 0).setView(layout).show();
    

    你打电话后看到的 makeText 我们打电话回来时 setGravity 到目前为止

    我怎么能在我自己的课上做到这一点?我需要做什么特别的事吗?

    6 回复  |  直到 7 年前
        1
  •  86
  •   Thomas Lötzer    14 年前

    这种模式称为“流畅的界面”(参见 Wikipedia )

    只是 return this; 而不是什么都不返回。

    例如

    public void makeText(String text) {
        this.text = text;
    }
    

    将成为

    public Toast makeText(String text) {
        this.text = text;
        return this;
    }
    
        2
  •  10
  •   subhashis    10 年前
    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();
        }
    }
    

    方法链接, 也称为命名 参数习语 ,是在面向对象编程语言中调用多个方法调用的常用语法。每个方法都返回一个对象,允许在单个语句中将调用链接在一起。链接是句法上的糖分,它消除了中间变量的需要。方法链也被称为火车残骸,这是因为在同一行中,随着更多方法被链接在一起而出现的方法的数量不断增加,即使方法之间经常添加换行符。

    类似的语法是 方法级联 ,其中,在方法调用之后,表达式计算为当前对象,而不是方法的返回值。通过让方法返回当前对象本身,可以使用方法链接来实现级联。级联是Fluent接口中的一项关键技术,由于链接在面向对象的语言中得到了广泛的实现,而级联则不是,这种“通过返回链接进行级联”的形式通常被简单地称为“链接”。链接和级联都来自Smalltalk语言。

        3
  •  4
  •   Gilbert Le Blanc    13 年前

    从你的例子来看:

    toast.makeText(text).setGravity(gravity.top,0,0).setView(layout).show();

    链中的每个方法都必须返回类或接口。链中的下一个方法必须是返回类的一部分。

    我们从吐司开始。方法MakeText(在类Toast中定义为静态方法)必须返回类或接口。在这里,它返回类重力的一个实例。

    方法setGravity(在类重力中定义)返回类视图的实例,

    方法setview(在类视图中定义)返回类jpanel的实例。

    这个链子可以一步一步地写出来。

    Gravity gravity = Toast.makeText(text);
    View view       = gravity.setGravity(Gravity.TOP, 0, 0);
    JPanel panel    = view.setView(layout);
    panel.show();
    

    将链写为链将从源代码中删除所有中间实例变量。

        4
  •  3
  •   Guillaume    14 年前

    在Google上搜索构建器模式或流畅的界面,以获得更多有关这方面的详细信息。

    在方法的末尾返回“this”,这在大多数情况下都可以实现。

        5
  •  1
  •   Purushotham Kumar    7 年前

    添加返回这个;对于这个类来说肯定有帮助,但是对于子类来说失败了。

    如果您希望将链接行为继承到子类,那么也可以更改类签名,如下所示:

    类超类<子类扩展超类>

    这样,所有子类都将继承方法链接。

    例子:

    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());
        }
    
    }
    
        6
  •  -1
  •   eric    13 年前

    或者你可以使用 Diezel 它基于FluentAPI的正则表达式生成您需要的所有接口。