ミックスインと継承


回答:


66

ミックスインは通常、多重継承で使用されます。したがって、その意味では「違いはありません」。

詳細は、ミックスインがスタンドアロンオブジェクトとしてはほとんど役に立たないということです。

たとえば、「ColorAndDimension」という名前のミックスインがあり、色プロパティと幅と高さを追加するとします。

これで、ColorAndDimensionをShapeクラス、Spriteクラス、Carクラスなどに追加できます。これらはすべて同じインターフェイス(たとえば、get / setColor、get / setHeight / Widthなど)を持ちます。

つまり、一般的なケースでは、ミックスインIS継承です。しかし、ミックスインが「プライマリ」クラスなのか単なるミックスインなのかは、ドメイン全体におけるクラスの役割の問題であると主張できます。


編集-明確にするために。

はい、ミックスインは、今日の専門用語では、関連する実装を持つインターフェースと考えることができます。これは、単純で古い、日常的なクラスを使用した、単純で古い日常的な多重継承です。それはたまたまMIの特定のアプリケーションです。ほとんどの言語はミックスインに特別なステータスを与えません。スタンドアロンで使用されるのではなく、「混合」するように設計されたクラスにすぎません。


29

ミックスインと継承の違いは何ですか?

ミックスインは、追加の機能を提供するために継承できるベースクラスです。擬似コードの例:

class Mixin:
    def complex_method(self):
        return complex_functionality(self)

「ミックスイン」という名前は、他のコードと混合することを意図していることを示しています。したがって、推測では、ミックスインクラスを単独でインスタンス化することはありません。次のオブジェクトにはデータがなく、インスタンス化してcomplex_methodを呼び出すことは意味がありません。(その場合は、クラスの代わりに関数を定義することもできます。)

>>> obj = Mixin()

多くの場合、ミックスインは他の基本クラスで使用されます。

したがって、ミックスインは継承のサブセット、つまり特殊なケースです。

単一継承よりもミックスインを使用する利点は、機能のコードを一度に記述してから、複数の異なるクラスで同じ機能を使用できることです。不利な点は、使用する場所以外の場所でその機能を探す必要があるかもしれないということです。そのため、近くに置くことでその不利な点を軽減するのが良いでしょう。

多くの同様のコードをユニットテストしている単一継承よりも使用する必要があるミックスインを個人的に見つけましたが、テストケースはベースケースの継承に基づいてインスタンス化され、コードを近くに保つ唯一の方法ですハンド(および同じモジュール内)は、カバレッジ番号をいじることなく、オブジェクトから継承し、子ケースにユニバーサルテストケースベースとそれらにのみ適用されるカスタムベースの両方から継承させます。

ミックスインと抽象的な基本クラスとの比較および対照

どちらも、インスタンス化することを意図していない親クラスの形式です。

ミックスインは、機能を提供しますが、それを直接使用することができません。ユーザーは、(サブ)クラスを通じてそれを使用することを目的としています。

抽象基底クラスは、インターフェイスを提供しますが、使用可能な機能はありません。ユーザーは、インターフェイスによって呼び出される機能を作成することを目的としています。

class Abstraction(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def complex_method(self):
        return complex_functionality(self)

ここでは、具体的なメソッドで機能を実装するためにサブクラスが必要であるため、このオブジェクトをインスタンス化することはできません(からの機能にアクセスできます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モジュールの一部のクラスは、継承を介して機能を提供する親クラスと、サブクラスによって実装する必要がある抽象インターフェースの例です。これらのアイデアは相互に排他的ではありません。

概要

簡単に言うと、ミックスインは、それ自体ではインスタンス化しない基本クラスであり、通常、多重継承でセカンダリ基本クラスとして使用されます。


18

ミックスインは、実装目的で使用される(複数の)継承の特定の制限されたケースです。一部の言語(Rubyなど)では、一般化された多重継承をサポートせずにそれをサポートしています。


7

Mixinは抽象的な概念であり、その要件を満たすものはすべてMixinと見なすことができます。

以下はウィキペディアの定義です。

オブジェクト指向プログラミング言語では、ミックスインは他のクラスの親クラスでなくても他のクラスが使用できるメソッドを含むクラスです。これらの他のクラスがミックスインのメソッドにアクセスする方法は、言語によって異なります。ミックスインは、「継承」されているのではなく「含まれている」と表現される場合があります。

つまり、継承との主な違いは、ミックスインが継承のように「is-a」関係を持つ必要がないことです。

実装の観点からは、実装とのインターフェースと考えることができます。たとえば、Javaが多重継承をサポートしている場合、Javaの抽象クラスはミックスインと見なすことができます。


太字の文章を理解するのに苦労しています。「Aとの(B?の)違いは、(B?)がAのようなものを必要とすることだ」と思われます。違いや類似点について話していますか?
RayLuo 2016年

@RayLuoおっと...私はいくつかのタイプミスをしました。混乱させてすみません。ミックスインは「is-a」関係を持つ必要はありません
Alex

3

「ミックスインは、他のクラスまたはミックスインと組み合わせることを目的としているという意味で、クラスのフラグメントです。」-DDJ

ミックスインは、スタンドアロンでの使用を目的としていないクラスまたはコードフラグメントですが、代わりに別のクラス内で使用することになっています。メンバーフィールド/変数として、またはコードセグメントとして構成します。私は後者に最も多く触れています。それはコピー貼り付けの定型コードより少し良いです。

これは、主題を紹介する素晴らしいDDJ記事です。

Half-Life 2 / "Source" SDKは、C ++ミックスインの良い例です。その環境では、マクロは、特定の「フレーバー」または機能をクラスに与えるために追加できるコードのかなりのブロックを定義します。

ソースWikiの例:論理エンティティの作成を見てください。コード例では、DECLARE_CLASSマクロをミックスインと見なすことができます。ソースSDKはミックスインを広範囲に使用して、データアクセスコードを標準化し、動作をエンティティに割り当てます。


0

多重継承により、新しいクラスは複数のスーパークラスから構成される場合があります。スーパークラスで定義されたメソッドのみを呼び出すことができます。

一方、mixinは、さまざまな親クラスの動作を特化するために使用できる抽象サブクラスです。ミックスインは、sayHello(): Stringそのようなメソッドを定義していなくても、メソッド(たとえば)を呼び出すことがあります。

mixin M {
    name: String
    defmethod greetings() { print sayHello() + " " + name}
}

ご覧のとおり、sayHello()どこにも定義されていなくても呼び出すことができます。MクラスCにミックスインを追加する場合C、はsayHello()メソッドを提供する必要があります。


1
最初のステートメントの正確さがわからない-クラスは独自のメソッドを定義できる
EugeneMi

0

ミックスイン継承を意味するものではないことに注意してください。ウィキペディアによると、Mixinは次のとおりです。

オブジェクト指向プログラミング言語では、ミックスインは他のクラスの親クラスでなくても他のクラスが使用できるメソッドを含むクラスです。これらの他のクラスがミックスインのメソッドにアクセスする方法は、言語によって異なります。ミックスインは、「継承」されているのではなく「含まれている」と表現される場合があります。

具体的には、perlなどの言語では、エクスポーターモジュールを使用してミックスインを追加できます。

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

私はそのばかげた例を知っています、しかし、それは全体のポイントを取得します...


0

tl; dr

ミックスインと多重継承は同じ形式です。しかし、セマンティクスは異なります。mixinには、関数の実装を提供する基本クラスがあります。継承のために、基本クラスはインターフェースを提供し、サブクラスは実装を持っています。

とにかく、構成はミックスインIMOよりも優先されます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.