Answers:
mixin通常与多重继承一起使用。因此,从这个意义上讲,没有任何区别。
细节是,mixin很少用作独立对象。
例如,假设您有一个名为“ ColorAndDimension”的混合,它添加了color属性以及width和height。
现在,您可以将ColorAndDimension添加到Shape类,Sprite类,Car类等中。它们都将具有相同的接口(例如get / setColor,get / setHeight / Width等)。
因此,在一般情况下,mixin IS继承。但是您可以争辩说,关于mixin是“主要”类还是仅仅是mixin,这与类在整个领域中的作用有关。
编辑-只是为了澄清。
是的,在当今的现代术语中,可以将mixin视为具有相关实现的接口。实际上,使用普通的,日常的类只是普通的,日常的,多重继承。它恰好是MI的特定应用。大多数语言都没有给出特殊的混合状态。它只是一个旨在“混入”而不是独立使用的类。
mixin和继承之间有什么区别?
一个混合式是一个基类,你可以继承,以提供额外的功能。伪代码示例:
class Mixin:
def complex_method(self):
return complex_functionality(self)
名称“ mix-in”表示打算与其他代码混合。因此,推断是您不会自行实例化混合类。以下对象没有数据,对其进行实例化以调用complex_method毫无意义。(在这种情况下,您也可以只定义一个函数而不是一个类。)
>>> obj = Mixin()
通常,混入与其他基类一起使用。
因此,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
模块中的某些类是父类的示例,它们均通过继承和必须由子类实现的抽象接口提供功能。这些想法不是相互排斥的。
简而言之,混入只是您自己不会实例化的基类,通常在多重继承中用作辅助基类。
Mixin是一个抽象概念,任何符合其要求的东西都可以视为mixin。
这是维基百科的定义。
在面向对象的编程语言中,mixin是一个类,其中包含供其他类使用的方法,而不必成为其他类的父类。这些其他类如何获得对mixin方法的访问权限取决于语言。混入有时被描述为“包含”而不是“继承”。
简而言之,与继承的主要区别在于,混入不需要像继承那样具有“是”关系。
从实现的角度来看,您可以将其视为实现的接口。例如,如果Java支持多重继承,则Java中的抽象类可以被视为mixin。
“从某种意义上说,mixin是一类的片段,它打算与其他类或mixin组成。” -DDJ
mixin是一个类或代码片段,不适合独立使用,而应该在另一个类中使用。将其组成一个成员字段/变量或一个代码段。我对以后的接触最多。它比粘贴复制样板代码要好一些。
Half-Life 2 /“ Source” SDK是C ++ mixins的一个很好的例子。在这种环境下,宏定义了可扩展的代码块,可以添加这些代码块以为类提供特定的“风味”或功能。
看一下Source Wiki示例:Authoring a Logical Entity。在示例代码中,DECLARE_CLASS宏可以被视为混合。Source SDK广泛使用mixin来标准化数据访问代码并将行为归于实体。
具有多个继承,新类可以由多个超类组成。您只能调用任何超类中定义的方法。
另一方面,mixin是一个抽象子类,可用于专门化各种父类的行为。Mixins可以调用方法(例如sayHello(): String
),即使它们没有定义这样的方法。
mixin M {
name: String
defmethod greetings() { print sayHello() + " " + name}
}
如您所见,sayHello()
即使未在任何地方定义它,您也可以调用。如果将mixin添加M
到class C
,C
则应提供sayHello()
方法。
我认为必须注意,mixin并不意味着继承。根据维基百科,Mixin是:
在面向对象的编程语言中,mixin是一个类,其中包含供其他类使用的方法,而不必成为其他类的父类。这些其他类如何获得对mixin方法的访问权限取决于语言。混入有时被描述为“包含”而不是“继承”。
具体来说,可以使用Exporter模块以perl之类的语言添加mixins:
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'));
}
可以一次混入包含一个或多个方法的任何模块中:
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();
我知道这是一个荒谬的例子,但是,它可以使您理解...