mixin和inheritance有什么区别?
答案 0 :(得分:50)
混合输入通常与多重继承一起使用。所以,从这个意义上讲,“没有区别”。
细节是Mix in很少用作独立对象。
例如,假设您有一个名为“ColorAndDimension”的混合名称,它会添加颜色属性以及宽度和高度。
现在,您可以将ColorAndDimension添加到,例如,Shape类,Sprite类,Car Class等。它们都将具有相同的接口(例如get / setColor,get / setHeight / Width等)
因此,在通用情况下,一个混合IS继承。但是你可以认为这是一个关于类在整个领域中的作用的问题,关于混合是一个“主要”类还是仅仅是混合。
编辑 - 只是为了澄清。
是的,在今天的现代术语中,可以考虑将Mix In视为具有相关实现的接口。它实际上只是简单,陈旧,日常的多重继承,使用普通的,老式的日常课程。它恰好是MI的特定应用。大多数语言都没有混合在任何特殊状态下,它只是一个被设计为“混合”的类,而不是单独使用。
答案 1 :(得分:23)
mixin和inheritance有什么区别?
mix-in 是您可以继承的基类,以提供其他功能。伪代码示例:
class Mixin:
def complex_method(self):
return complex_functionality(self)
名称“mix-in”表示它打算与其他代码混合使用。因此,推断是您不会自己实例化混合类。以下对象没有数据,将它实例化为调用complex_method是没有意义的。 (在这种情况下,你也可以只定义一个函数而不是一个类。)
>>> obj = Mixin()
混合常常与其他基类一起使用。
因此 mixins是继承的子集或特例。
使用混合而不是单一继承的优点是,您可以为函数编写一次代码,然后在多个不同的类中使用相同的功能。缺点是您可能需要在其他位置查找该功能,因此最好通过将其保持在附近来缓解该缺点。
我个人发现使用单一继承所需的混合,我们正在对许多类似的代码进行单元测试,但是测试用例是基于它们对基本情况的继承而实例化的,并且是保持测试用例的唯一方法。在没有弄乱覆盖号的情况下,代码就在眼前(并且在同一个模块中)是从对象继承的,并且子例子继承自通用测试用例库和仅适用于它们的自定义库。
两者都是父类的一种形式,不打算实例化。
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
模块中的一些类是父类的示例,它们都通过继承提供功能,而抽象接口则必须由子类实现。这些想法并不相互排斥。
简单地说,混合只是一个你不会自己实例化的基类,通常在多重继承中用作辅助基类。
答案 2 :(得分:18)
mix-in是用于实现目的的(多个)继承的特定,受限制的情况;某些语言(例如Ruby)支持它而不支持广义多重继承。
答案 3 :(得分:4)
Mixin是一个抽象概念,任何满足其要求的东西都可以被认为是混合物。
这是维基百科的定义。
在面向对象的编程语言中,mixin是一个包含其他类使用的方法的类,而不必是其他类的父类。其他类如何访问mixin的方法取决于语言。 Mixins有时被描述为“包含”而不是“继承”。
简而言之,与继承的关键区别在于混合不需要像继承一样具有“is-a”关系。
从实现的角度来看,您可以将其视为实现的接口。例如,如果Java支持多重继承,Java中的抽象类可以被视为mixin。
答案 4 :(得分:3)
“mixin是一个类的片段,意思是它与其他类或mixin一起组成。” -DDJ
mixin是一个类或代码片段,不是为了独立使用,而是你应该在另一个类中使用它。将其组合为成员字段/变量或代码段。我对后来的曝光率最高。它比复制粘贴样板代码好一点。
Here's a great DDJ article that introduces the subject.
Half-Life 2 /“Source”SDK是C ++ mixins的一个很好的例子。在该环境中,宏定义了相当大的代码块,可以添加这些代码块以使类具有特定的“味道”或特征。
查看Source wiki示例:Authoring a Logical Entity。在示例代码中,DECLARE_CLASS宏可以被视为mixin。 Source SDK广泛使用mixin来标准化数据访问代码并将行为归因于实体。
答案 5 :(得分:0)
通过多重继承,新类可以由多个超类组成。您只能调用任何超类中定义的方法。
另一方面,mixin是一个抽象子类,可用于专门化各种父类的优点。 Mixins可以调用方法(例如sayHello(): String
),即使它们没有定义这样的方法。
mixin M {
name: String
defmethod greetings() { print sayHello() + " " + name}
}
如您所见,即使未在任何地方定义,也可以致电sayHello()
。如果您将mixin M
添加到课程C
,则C
应该提供sayHello()
方法。
答案 6 :(得分:0)
我认为重要的是要注意, mixin 并不意味着继承。根据维基百科,Mixin是:
在面向对象的编程语言中,mixin是一个类 包含其他类使用的方法,而不必是 那些其他类的父类。那些其他课程如何获益 访问mixin的方法取决于语言。 Mixins是 有时被描述为&#34;包括&#34;而不是&#34;继承&#34;。
具体来说,在像perl这样的语言中,可以使用Exporter模块添加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();
我知道这是一个荒谬的例子,但是,它得到了重点......
答案 7 :(得分:0)
TL;博士
mixin和多重继承具有相同的形式。但是有不同的语义:mixin有基本类提供函数实现。对于继承,基类提供接口和子类具有实现。但无论如何,组合物优于mixin IMO
答案 8 :(得分:0)
Mixin以更“插件”式的方式广泛使用。
它们是相同的,但是在不同的上下文中它们每个。通常,当我们谈论继承时,我们谈论的是单一继承,而mixin是允许多重继承的结构。
由于以下原因,这是一种在OOP世界中引起争议的语言构造:
但是,除此之外,它是一种强大的构造,可用于各种语言和框架,例如: