クラスを更に掘り下げる! (4/6)
作成:2018-04-21 09:25
更新:2018-04-21 09:25
更新:2018-04-21 09:25
■withによるミックスイン
インターフェイスは、追加したクラスにあるメソッドの実装を義務付けるものでしたが、そうではなくて、「他のクラスのメソッドだけちゃっかり利用したい」なんてこともありますよね。こういうとき、継承は1つのクラスしか利用できません。それ以外のクラスの機能も使いたいときは? それは「ミックスイン」という機能を利用するのです。
ミックスインは、クラスの継承の際に、他のクラスの機能を「混ぜて」しまうものです。これは以下のように記述をします。
withで指定したクラスは、継承するわけではありません。ただ、そこにある機能だけをもらって使えるようにするだけです。ですから、例えばsuperを使ってミックスインしたクラスのメソッドを呼び出したりすることはできません。
また、ミックスインするクラスは、お互いのクラスにどんな機能があるかは知りません。ですから、完全に独立して機能するメソッドを持つクラスでないとミックスインでは利用できないでしょう。
ミックスインは、「継承元とどちらを優先するか?」という問題を提起します。例えば、継承するスーパークラスと、ミックスインするクラスの両方に同じメソッドがあったとしましょう。この場合、メソッドを呼び出したらどちらのものが呼び出されるのでしょうか?
正解は、「ミックスインしたクラスのメソッド」です。ミックスインしたクラスに、継承したクラスと同じメソッドがあったら、そちらが呼び出されます。ミックスインは、継承に「後から追加した」ものですから、追加したこちらが優先されるのでしょう。
ミックスインは、クラスの継承の際に、他のクラスの機能を「混ぜて」しまうものです。これは以下のように記述をします。
class クラス名 extends スーパークラス with 追加クラス, …… {extendsで継承するクラスを指定した後に、「with」をつけ、ミックスインしたいクラスを指定します。複数ある場合はカンマで区切って記述をします。こうすると、extendsで指定したクラスを継承するのですが、その際にwithで指定したクラスの機能も混ぜて使えるようにしてくれるのです。
……略……
}
withで指定したクラスは、継承するわけではありません。ただ、そこにある機能だけをもらって使えるようにするだけです。ですから、例えばsuperを使ってミックスインしたクラスのメソッドを呼び出したりすることはできません。
また、ミックスインするクラスは、お互いのクラスにどんな機能があるかは知りません。ですから、完全に独立して機能するメソッドを持つクラスでないとミックスインでは利用できないでしょう。
■継承とミックスイン、どっちが優先?
ミックスインは、「継承元とどちらを優先するか?」という問題を提起します。例えば、継承するスーパークラスと、ミックスインするクラスの両方に同じメソッドがあったとしましょう。この場合、メソッドを呼び出したらどちらのものが呼び出されるのでしょうか?
正解は、「ミックスインしたクラスのメソッド」です。ミックスインしたクラスに、継承したクラスと同じメソッドがあったら、そちらが呼び出されます。ミックスインは、継承に「後から追加した」ものですから、追加したこちらが優先されるのでしょう。
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。
●プログラム・リスト●
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | void main() { MyData hanako = new MyData.make( 'Hanako' , 'hanako@flower' , 28 ); hanako.printData(); hanako.printIt(hanako.getData()); } class MyObj { String name; String mail; num age; Map getData(){ return { 'name' : this .name, 'mail' : this .mail, 'age' : this .age}; } } class Printing { void printIt(Map data){ for (var ky in data.keys){ print(ky + ":" + data[ky].toString()); } } } class MyData extends MyObj with Printing { MyData() : this .make( 'noname' , 'no@mail' , 0 ); MyData.make(String name, String mail, num age){ this .name = name; this .mail = mail; this .age = age; } void printData(){ String re = '<MyObj "' + this .name + ' [' + this .mail + '"](' + this .age.toString() + ')>' ; print(re); } } |
※関連コンテンツ