導入
Mixin は、多重継承のクラス内のコードを再利用するためのメソッド パターンです。
ミックスインは、メソッド実装を提供するオブジェクト指向プログラミング言語のクラスです。他のクラスは、そのクラスのサブクラスにならずに、mixin
そのクラスのメソッドと変数にアクセスできます。
簡単に言うと、公式デザインは、多くのインターフェイスを実装する必要がなく、簡単に再利用できるクラスです。
アプリケーションシナリオ
たとえば、Anmal というスーパークラスがあり、その下に Mammal、Bird、Fish の 3 つのサブクラスがあり、その下にさらにサブクラスがあります。
ここでは例として Duck、Cat、Dove の 3 つのクラスを取り上げます。このうち、Duck は 3 つのメソッドすべてを実行でき、Cat は歩くことができ、Dove は歩いて飛ぶことができます。継承を使用して実装する場合は次のようになります。以下に続きます:
abstract class Animal{}
abstract class Swim{
void swim();
}
abstract class Walk{
void walk();
}
abstract class Fly{
void fly();
}
class Duck extends Animal implements Swim,Walk,Fly{
@override
void fly() => print("fly");
@override
void swim() => print("swim");
@override
void walk() => print("walk");
}
class Cat extends Animal implements Walk{
@override
void walk() => print("walk");
}
class Dove extends Animal implements Walk,Fly{
@override
void fly() => print("fly");
@override
void walk() => print("walk");
}
void main(){
Duck().swim();
Duck().walk();
Duck().fly();
Cat().walk();
Dove().fly();
Dove().walk();
}
出力結果は以下のとおりです。
dart も単一継承言語であるため、この使用法は Java とまったく同じですが、インターフェイス内のすべてのメソッドを書き直すのは非常に冗長です。現時点では 、インターフェイス内のメソッドを再利用できる方法はありますか?ミックスインを使用できます。
インターフェイスの代わりに mixin を使用します。mixin クラスのメソッドを再利用したい場合は、次のようにクラスの後に with キーワードを追加するだけです。
abstract class Animal{}
mixin Swim{
void swim() => print("swim");
}
mixin Walk{
void walk() => print("walk");
}
mixin Fly{
void fly() => print("fly");
}
class Duck extends Animal with Swim,Walk,Fly{}
class Cat extends Animal with Walk{}
class Dove extends Animal with Walk,Fly{}
void main(){
Duck().swim();
Duck().walk();
Duck().fly();
Cat().walk();
Dove().fly();
Dove().walk();
}
最終的な出力結果は上記と全く同じで、特殊なケースをクラスに実装する方法はインターフェースを使用する方法と同じで、直接書き換えるだけです。
高度な使用法
ミックスインの線形化プロパティ
混ぜるクラスに同じメソッドが存在する場合、それはどのように呼び出されるでしょうか? たとえば、 run() メソッドは Person クラスと A クラスの両方で定義されているので、 Male クラスで呼び出してみましょう。
class Person{ run() => print("person"); }
mixin A{ run() => print("A"); }
class Male extends Person with A{}
main(){
Male().run();
}
結果は次のとおりです。
-------------------------------------------------- -------------------------------------------------- ---
A
ここではクラス A の run() メソッドのみが実行されます。dart には線形化と呼ばれる文法機能があります。
上記のミックスインのコードは次と同等です。
Class PersonA = Person with A
Class Male extends PersonA;
これは、A によって書き換えられる Person クラスの run() メソッドと同等なので、A クラスの書き換えられた run() メソッドが呼び出されます。
では、そのメソッドを Person クラスで呼び出す方法はあるのでしょうか? 答えはもちろん「はい」で、とても簡単です。継承なので、親メソッドと super.run() を直接呼び出すことができます。
class Person{ run() => print("person"); }
mixin A{
@override
run() {
super.run();
print("A");
}
}
class Male extends Person with A{}
main(){
Male().run();
}
出力は次のとおりです。
person
A
の上
mixin を使用する場合、on キーワードを使用して制限できます。このクラスでミックスする場合は、最初に on の後ろのクラスを継承またはミックスする必要があります。
好き:
class Person{ run() => print("person"); }
mixin A{ run() => print("A"); }
mixin C on Person{
@override
run() {
super.run();
print("C");
}
}
//这里还可以是
//class Femal extends Person with A,C{}
class Female with A,Person,C{} //混入时,Person类必须在C之前
main(){
Female().run();
}
最終出力
person
C
参考
dart におけるミックスイン分析 - Attack on Summer のブログ - CSDN ブログ - dart mixin