多くの 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();
}
}
名前付きパラメーター idiomとも呼ばれるメソッド チェーンは、オブジェクト指向プログラミング言語で複数のメソッド呼び出しを呼び出すための一般的な構文です。各メソッドはオブジェクトを返すため、呼び出しを 1 つのステートメントにまとめることができます。連鎖は、中間変数の必要性を排除する構文糖衣です。メソッドチェーンは、メソッド間に改行が追加されることが多いにもかかわらず、より多くのメソッドが一緒にチェーンされるにつれて発生する、同じ行に次々と来るメソッドの数の増加により、列車事故としても知られています。
同様の構文はメソッド カスケードです。この場合、メソッド呼び出しの後、式はメソッドの戻り値ではなく、現在のオブジェクトに評価されます。カスケードは、メソッドが現在のオブジェクト自体 (this) を返すようにすることで、メソッド チェーンを使用して実装できます。カスケードは流暢なインターフェースの重要なテクニックであり、連鎖はオブジェクト指向言語で広く実装されていますが、カスケードは実装されていないため、この形式の「これを返すことによる連鎖によるカスケード」はしばしば単に「連鎖」と呼ばれます。チェーンとカスケードはどちらも Smalltalk 言語から来ています。
あなたの例から:
Toast.makeText(テキスト).setGravity(Gravity.TOP, 0, 0).setView(レイアウト).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 でビルダー パターンまたは流暢なインターフェイスを検索してください。
ほとんどの場合、メソッドの最後で「this」を返すとうまくいきます。
または、流れるような API の正規表現に基づいて必要なすべてのインターフェイスを生成するDiezelを使用できます。