web-dev-qa-db-fra.com

Comment faire le chaînage de méthode en Java? o.m1 (). m2 (). m3 (). m4 ()

J'ai vu dans beaucoup de Java qu'après une méthode que nous appelons une autre, voici un exemple.

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

Comme vous le voyez après avoir appelé makeText au retour, nous appelons setGravity et jusqu'à présent

Comment puis-je faire cela avec mes propres cours? Dois-je faire quelque chose de spécial?

40
Pentium10

Ce modèle est appelé "Interfaces fluides" (voir Wikipedia )

Juste return this; des méthodes au lieu de ne rien retourner.

Donc par exemple

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

deviendrait

public Toast makeText(String text) {
    this.text = text;
    return this;
}
90
Thomas Lötzer
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();
}

}

Sans chaînage de méthode

   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();
    }
}

Chaînage de méthodes, également connu sous le nom de idiome de paramètre, est une syntaxe courante pour appeler plusieurs appels de méthode dans des langages de programmation orientés objet. Chaque méthode renvoie un objet, permettant aux appels d'être enchaînés ensemble dans une seule instruction. Le chaînage est du sucre syntaxique qui élimine le besoin de variables intermédiaires. Une chaîne de méthodes est également connue comme une épave de train en raison de l'augmentation du nombre de méthodes qui se succèdent dans la même ligne qui se produit lorsque plusieurs méthodes sont enchaînées, même si des sauts de ligne sont souvent ajoutés entre les méthodes.

Une syntaxe similaire est méthode en cascade, où après l'appel de la méthode, l'expression est évaluée à l'objet actuel, pas la valeur de retour de la méthode. La mise en cascade peut être implémentée à l'aide du chaînage de méthodes en demandant à la méthode de renvoyer l'objet actuel lui-même (this). La cascade est une technique clé dans les interfaces fluides, et comme le chaînage est largement implémenté dans les langages orientés objet alors que la cascade ne l'est pas, cette forme de "cascade par chaînage en renvoyant ceci" est souvent appelée simplement "chaînage". Le chaînage et la cascade proviennent du langage Smalltalk.

12
subhashis

De votre exemple:

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

Chaque méthode de la chaîne doit renvoyer une classe ou une interface. La méthode suivante de la chaîne doit faire partie de la classe renvoyée.

Nous commençons avec Toast. La méthode makeText, qui est définie comme une méthode statique dans la classe Toast, doit renvoyer une classe ou une interface. Ici, il retourne une instance de la classe Gravity.

La méthode setGravity, qui est définie dans la classe Gravity, retourne une instance de la classe View,

La méthode setView, qui est définie dans la classe View, renvoie une instance de la classe JPanel.

Cette chaîne pourrait être écrite étape par étape.

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

L'écriture de la chaîne en tant que chaîne supprime toutes les variables d'instance intermédiaires du code source.

6
Gilbert Le Blanc

Recherchez le modèle de générateur ou l'interface fluide sur google pour avoir plus de détails à ce sujet.

Renvoyer "ceci" à la fin de votre méthode peut faire l'affaire dans la plupart des cas.

4
Guillaume

Ajout de retour ceci; aiderait sûrement à enchaîner pour cette classe mais échouerait pour les sous-classes.

Si vous souhaitez également que le comportement de chaînage soit hérité des sous-classes, modifiez la signature de votre classe comme ci-dessous:

Classe SuperClass <La sous-classe étend SuperClass> {}

De cette façon, toutes les sous-classes hériteront du chaînage de méthode.

Exemple:

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());
    }

}
1
Purushotham Kumar