ミックスインと継承の違いは何ですか?
9 に答える
mixin は通常、多重継承で使用されます。そういう意味では「違いがない」。
詳細は、ミックスインがスタンドアロン オブジェクトとして役立つことはめったにないということです。
たとえば、色のプロパティと幅と高さを追加する「ColorAndDimension」という名前の mixin があるとします。
ここで、ColorAndDimension を Shape クラス、Sprite クラス、Car クラスなどに追加できます。これらはすべて同じインターフェイス (get/setColor、get/setHeight/Width など) を持ちます。
したがって、一般的なケースでは、ミックスインは継承です。しかし、ミックスインが「プライマリ」クラスなのか、単にミックスインなのかは、ドメイン全体におけるクラスの役割の問題であると主張できます。
編集 - 明確にするために。
はい、ミックスインは、今日の現代用語では、実装が関連付けられたインターフェイスと見なすことができます。それは実際には、単純で古い日常的なクラスを使用した、単純で古くて日常的な多重継承です。それはたまたま MI の特定のアプリケーションです。ほとんどの言語では、ミックスインに特別なステータスはありません。スタンドアロンで使用するのではなく、「ミックスイン」するように設計されたクラスです。
ミックスインと継承の違いは何ですか?
ミックスインは、追加機能を提供するために継承できる基本クラスです。擬似コードの例:
class Mixin:
def complex_method(self):
return complex_functionality(self)
「ミックスイン」という名前は、他のコードと混合することを意図していることを示しています。そのため、ミックスイン クラスを単独でインスタンス化することはないと推測されます。次のオブジェクトにはデータがないため、complex_method を呼び出すためにインスタンス化しても意味がありません。(その場合、クラスの代わりに関数を定義することもできます。)
>>> obj = Mixin()
多くの場合、ミックスインは他の基本クラスで使用されます。
したがって、ミックスインは継承のサブセット、または特殊なケースです。
単一の継承よりも mix-in を使用する利点は、機能のコードを 1 回記述すれば、同じ機能を複数の異なるクラスで使用できることです。欠点は、その機能が使用されている場所以外の場所で探す必要がある場合があることです。そのため、近くに置いておくことでその欠点を軽減することをお勧めします。
私は個人的に、多くの同様のコードを単体テストしている単一の継承よりもミックスインを使用する必要があることを発見しましたが、テストケースは基本ケースの継承に基づいてインスタンス化され、コードを近くに保つ唯一の方法です手 (および同じモジュール内) は、カバレッジ番号をいじることなく、オブジェクトから継承し、子ケースにユニバーサル テスト ケース ベースとそれらにのみ適用されるカスタム ベースの両方から継承させることです。
抽象基本クラスとの比較対照におけるミックスイン
どちらも、インスタンス化を意図していない親クラスの形式です。
mixinは機能を提供しますが、直接使用することはできません。ユーザーは、(サブ) クラスを通じてそれを使用することを意図しています。
抽象基本クラスはインターフェイスを提供しますが、使用可能な機能はありません。ユーザーは、インターフェイスによって呼び出される機能を作成することを目的としています。
class Abstraction(metaclass=abc.ABCMeta):
@abc.abstractmethod
def complex_method(self):
return complex_functionality(self)
ここでは、具象メソッドを使用して機能を実装するサブクラスが必要なため、このオブジェクトをインスタンス化することはできません (ただし、 from 内の機能にアクセスすることはできますsuper()
)。
>>> obj = Abstraction()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Abstraction with
abstract methods complex_method
Python では、abc
モジュール内の一部のクラスは、サブクラスによって実装する必要がある継承と抽象インターフェイスを介して機能を提供する親クラスの例です。これらのアイデアは相互に排他的ではありません。
概要
簡単に言うと、ミックスインは、それ自体ではインスタンス化しない単なる基本クラスであり、通常は多重継承で 2 番目の基本クラスとして使用されます。
mix-in は、実装目的で使用される (複数の) 継承の特定の制限されたケースです。一部の言語 (Ruby など) は、一般化された多重継承をサポートせずにサポートしています。
「ミックスインは、他のクラスまたはミックスインと組み合わせることを意図しているという意味で、クラスのフラグメントです。」-DDJ
ミックスインは、スタンドアロンでの使用を意図していないクラスまたはコード フラグメントですが、代わりに別のクラス内で使用することになっています。メンバー フィールド/変数またはコード セグメントとして構成します。私は後者に最も多く露出しています。ボイラープレート コードをコピー アンド ペーストするよりは少しましです。
Half-Life 2 / "Source" SDK は、C++ ミックスインの好例です。その環境では、マクロは、クラスに特定の「フレーバー」または機能を与えるために追加できるかなり大きなコード ブロックを定義します。
Source wiki の例を見てください: Authoring a Logical Entity . コード例では、DECLARE_CLASS マクロを mixin と見なすことができます。Source SDK は mixin を広範囲に使用して、データ アクセス コードを標準化し、動作をエンティティに割り当てます。
ミックスインは、より「プラグイン」のような方法で広く使用されています。
それらは同じですが、それぞれ異なるコンテキストにあります。通常、継承について話すときは、SINGLE 継承について話します。mixin は、MULTIPLE 継承を可能にするコンストラクトです。
これは、次の理由により、OOP の世界で非常に物議をかもしている言語構造です。
- 解決しなければならない曖昧さ
- 多くの場合、「ミックスイン」クラスは単独では機能せず、他のミックスインと競合する可能性があります
- 2 つのスーパークラスが同じクラスから継承できる「ダイヤモンド継承問題」が発生する可能性があります。
しかし、それはさておき、さまざまな言語やフレームワークで使用される強力な構成要素です。いくつかの例を次に示します。
- ジャンゴ
- タイプスクリプト
多重継承では、新しいクラスが複数のスーパークラスから構成される場合があります。いずれかのスーパークラスで定義されたメソッドのみを呼び出すことができます。
一方、ミックスインは、さまざまな親クラスの動作を特殊化するために使用できる抽象サブクラスです。sayHello(): String
Mixin は、そのようなメソッドを定義していなくても、メソッド (たとえば ) を呼び出すことができます。
mixin M {
name: String
defmethod greetings() { print sayHello() + " " + name}
}
ご覧のとおり、sayHello()
どこにも定義されていなくても呼び出すことができます。mixinM
を classC
に追加すると、 はメソッドC
を提供する必要があります。sayHello()
tl;dr
mixin と多重継承は同じ形式です。ただし、セマンティクスは異なります。 mixin には、関数の実装を提供する基本クラスがあります。継承のために、基本クラスはインターフェースを提供し、サブクラスは実装を持っています。
とにかく、ミックスインIMOよりもコンポジションが優先されます
mixinは継承を意味しないことに注意することが重要だと思います。ウィキペディアによると、Mixinは次のとおりです。
オブジェクト指向プログラミング言語では、ミックスインは、他のクラスの親クラスでなくても他のクラスで使用できるメソッドを含むクラスです。他のクラスが mixin のメソッドにアクセスする方法は、言語によって異なります。Mixin は、「継承」ではなく「含まれる」と表現されることがあります。
具体的には、perl のような言語では、Exporter モジュールを使用してミックスインを追加できます。
package Mixins;
use Exporter qw(import);
our @EXPORT_OK = qw(pity);
# assumes it will be mixed-in to a class with a _who_do_i_pity method
sub pity {
my ($self) = @_;
printf("I pity %s\n", $self->_who_do_i_pity('da foo'));
}
一度に 1 つ以上のメソッドを含む任意のモジュールに混在させることができます。
package MrT
use Mixins qw(pity);
sub new {
return bless({}, shift);
}
sub _who_do_i_pity {
return 'da foo!'
}
次に、MrT
モジュールで次のように使用できます。
use MrT;
MrT->new()->pity();
私はそれがばかげた例であることを知っていますが、それは要点を理解しています...