ミックスインと継承の違いは何ですか?
ミックスインは通常、多重継承で使用されます。したがって、その意味では、「違いはありません」。
詳細は、Mix inがスタンドアロンオブジェクトとしてほとんど役に立たないことです。
たとえば、色のプロパティと幅と高さを追加する「ColorAndDimension」という名前のミックスインがあるとします。
これで、ColorAndDimensionをシェイプクラス、スプライトクラス、カークラスなどに追加できます。これらはすべて同じインターフェイス(get/setColor、get/setHeight/Widthなど)を持ちます。
したがって、一般的な場合、Mix in IS継承。ただし、Mix inが「プライマリ」クラスであるかどうかに関するドメイン全体のクラスの役割の問題であると主張できます。または単に混ぜてください。
編集-明確にするために。
はい、現代の専門用語では、Mix Inは関連する実装とのインターフェースと考えることができます。これは、単純で古く、日常的なクラスを使用した、単純で古く、日常的な多重継承です。それはたまたまMIの特定のアプリケーションです。ほとんどの言語はミックスを提供しません特別なステータスでは、それはスタンドアロンで使用されるのではなく、「ミックスイン」されるように設計されたクラスです。
ミックスインと継承の違いは何ですか?
mix-inは、追加機能を提供するために継承できる基本クラスです。擬似コードの例:
_class Mixin:
def complex_method(self):
return complex_functionality(self)
_
「mix-in」という名前は、他のコードと混合することを意図しています。そのため、推測では、ミックスインクラスを単独でインスタンス化することはありません。次のオブジェクトにはデータがなく、complex_methodを呼び出すためにインスタンス化することは意味がありません。 (その場合、クラスの代わりに関数を定義することもできます。)
_>>> obj = Mixin()
_
多くの場合、ミックスインは他の基本クラスで使用されます。
したがって、ミックスインは継承のサブセット、または特殊なケースです
単一継承よりもミックスインを使用する利点は、機能のコードを一度作成してから、複数の異なるクラスで同じ機能を使用できることです。欠点は、使用する場所以外の場所でその機能を探す必要がある場合があることです。そのため、近くに置いてその欠点を軽減することをお勧めします。
私は個人的に、多くの同様のコードを単体テストしている単一継承で使用するために必要なミックスインを見つけましたが、テストケースはベースケースの継承に基づいてインスタンス化され、コードを近くに保つ唯一の方法です(同じモジュール内の)ハンドは、カバレッジ番号をいじらずに、オブジェクトから継承し、子ケースにユニバーサルテストケースベースとそれらにのみ適用されるカスタムベースの両方を継承させます。
どちらもインスタンス化されることを意図していない親クラスの形式です。
mixinは機能を提供しますが、直接使用することはできません。ユーザーは、(サブ)クラスを介して使用することを意図しています。
abstract base classはインターフェースを提供しますが、使用可能な機能はありません。ユーザーは、インターフェイスによって呼び出される機能を作成することを目的としています。
_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
モジュールの一部のクラスは、サブクラスによって実装される必要がある継承および抽象インターフェースを介して機能を提供する親クラスの例です。これらのアイデアは相互に排他的ではありません。
簡単に言えば、ミックスインは、それ自体ではインスタンス化しない基本クラスであり、通常、多重継承のセカンダリ基本クラスとして使用されます。
ミックスインは、実装目的で使用される(複数の)継承の特定の制限されたケースです。一部の言語(Rubyなど)は、一般化された多重継承をサポートせずにサポートしています。
Mixinは抽象的な概念であり、その要件を満たすものはすべてmixinと見なすことができます。
ウィキペディアの定義は次のとおりです。
オブジェクト指向プログラミング言語では、ミックスインは他のクラスの親クラスでなくても他のクラスが使用するメソッドを含むクラスです。それらの他のクラスがミックスインのメソッドにアクセスする方法は、言語によって異なります。ミックスインは、「継承」ではなく「包含」として説明されることがあります。
要するに、継承との主な違いは、ミックスインは継承のような「is-a」関係を持つ必要がないということです。
実装の観点からは、実装とのインターフェースと考えることができます。たとえば、Javaの抽象クラスは、Javaが多重継承をサポートしている場合、ミックスインと見なすことができます。
「ミックスインは、他のクラスまたはミックスインで構成されることを意図しているという意味で、クラスのフラグメントです。」 -DDJ
ミックスインは、スタンドアロンでの使用を目的としていないクラスまたはコードフラグメントですが、代わりに別のクラス内で使用することになっています。メンバーフィールド/変数またはコードセグメントとして構成します。私は後者に最も露出しています。ボイラープレートコードをコピーして貼り付けるよりも少し良いです。
Half-Life 2/"ソース" SDKは、C++ミックスインの優れた例です。その環境では、マクロはクラスに特定の「フレーバー」または機能を付与するために追加できるコードのかなりのブロックを定義します。
ソースwikiの例を見てください: Authoring a Logical Entity 。コード例では、DECLARE_CLASSマクロはミックスインと見なすことができます。 Source SDKは、ミックスインを広く使用して、データアクセスコードを標準化し、動作をエンティティに割り当てます。
多重継承では、新しいクラスは複数のスーパークラスから構成されます。スーパークラスで定義されたメソッドのみを呼び出すことができます。
一方、mixinは、さまざまな親クラスの動作を特殊化するために使用できる抽象サブクラスです。ミックスインは、そのようなメソッドを定義していなくても、メソッド(たとえば、sayHello(): String
)を呼び出すことができます。
_mixin M {
name: String
defmethod greetings() { print sayHello() + " " + name}
}
_
ご覧のように、sayHello()
はどこでも定義されていなくても呼び出すことができます。 mixin M
をクラスC
に追加する場合、C
はsayHello()
メソッドを提供する必要があります。
tl; dr
ミックスインと多重継承の形式は同じです。ただし、異なるセマンティクスがあります。mixinには、関数実装を提供する基本クラスがあります。継承のために、基本クラスはインターフェイスを提供し、サブクラスは実装を持ちます。
とにかく、mixin IMOよりも構成が優先されます
mixinはinheritanceを意味しないことに注意してください。ウィキペディアによると、 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();
私はその不条理な例を知っていますが、それは意味を成しています...