Mixin与inheritance

混合和inheritance有什么区别?

Mix in通常与多重inheritance一起使用。 所以,从这个意义上讲,“没有区别”。

细节是Mixin作为独立对象很less有用。

例如,假设您有一个混合名称“ColorAndDimension”,它添加一个颜色属性,宽度和高度。

现在,您可以将ColorAndDimension添加到Shape类,Sprite类,Car类等等。它们都具有相同的接口(比如get / setColor,get / setHeight / Width等)

所以,在通用情况下一个混合的ISinheritance。 但是你可以争辩说,这是整个领域中class级angular色的一个问题,这个class级是否是一个“主要”class,或者是一个混合class。

编辑 – 只是为了澄清。

是的,在今天的现代术语中,Mix In可以被认为是具有相关实现的接口。 这真的只是一个普通的,旧的,日常的多重inheritance,使用一个普通的,老的,日常的课程。 这恰好是MI的具体应用。 大多数语言不会混合在任何特殊的状态下,它只是一个被devise成“混合”的类,而不是单独使用。

混合是用于实现目的的(多重)inheritance的特定的,有限的情况; 一些语言(如Ruby)支持它,而不支持泛化的多重inheritance。

混合和inheritance有什么区别?

混合input是可以从中inheritance以提供附加function的基类。 名称“mix-in”表示打算将其与其他代码混合使用。 因此,推论是你不会自己实例化混合类。 混音通常与其他基类一起使用。 因此mixin是inheritance的一个子集或特殊情况。

在单一inheritance中使用混合的优点是,您可以一次性编写function的代码,然后在多个不同的类中使用相同的function。 缺点是,您可能需要在其他地方查找该function,而不是使用该function,所以通过保持这种function可以减轻这种不利影响。

我个人发现了一个混合使用单一inheritance的必要条件,我们unit testing了很多类似的代码,但是testing用例是基于它们对基本情况的inheritance来实例化的,唯一的方法就是保持代码靠近(并且在同一个模块中),而不会混淆覆盖数字,就是从对象inheritance,并让子案例同时从通用testing用例库和仅适用于它们的自定义基础inheritance。

Mixins与抽象基类的比较与对比

两者都是不希望被实例化的父类的一种forms。

mixin提供了function,但无法直接使用它。 用户打算通过(子)类来使用它。

抽象基类提供了一个接口,但没有可用的function。 用户打算创build接口调用的function。

在Python中, abc模块中的某些类是父类的示例,它们都通过inheritance提供function,并提供必须由子类实现的抽象接口。 这些想法并不相互排斥。

概要

简而言之,一个混合是一个基类,你不会自己实例化,并且通常用作多inheritance中的辅助基类。

“mixin是一个类的片段,意思是它要与其他类或混合类组成。” -DDJ

mixin是一个类或代码片段,不是为了独立使用,而是应该在另一个类中使用它。 可以将其作为成员字段/variables或代码段进行组合。 后来我接触最多。 这比复制粘贴样板代码好一点。

这是介绍这个主题的一篇很棒的DDJ文章。

Half-Life 2 /“Source”SDK是C ++ mixins的一个很好的例子。 在这个环境中,macros定义了大量的代码块,可以添加这些代码块来为这个类赋予一个特定的“风格”或特征。

查看源代码wiki示例: 编写逻辑实体 。 在示例代码中,DECLARE_CLASSmacros可以被认为是一个mixin。 Source SDK广泛使用mixin来标准化数据访问代码并将行为归于实体。

Mixin是一个抽象的概念,任何符合要求的东西都可以被认为是混合的。

这里是维基百科的一个定义。

在面向对象的编程语言中,mixin是一个包含其他类使用的方法的类,而不必是其他类的父类。 这些其他类如何获得mixin的方法取决于语言。 Mixin有时被描述为“包含”而不是“inheritance”。

总而言之,与inheritance的关键区别在于混合插件不需要像inheritance一样具有“是”的关系。

从实现的angular度来看,您可以将其视为与实现的接口。 例如,如果Java支持多重inheritance,那么Java中的抽象类可以被视为混合类。

通过多重inheritance,新类可以由多个超类构成。 您只能调用任何超类中定义的方法。

另一方面,mixin是一个抽象的子类,可以用来专门化各种父类的背景。 Mixins可能会调用一个方法(例如sayHello(): String ),即使它们没有定义这样的方法。

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

正如你所看到的,你可以调用sayHello()即使它没有被定义在任何地方。 如果将mixin M添加到C类,则C应该提供sayHello()方法。

我认为重要的是要注意, mixin并不意味着inheritance 。 根据维基百科, Mixin是:

在面向对象的编程语言中,mixin是一个包含其他类使用的方法的类,而不必是其他类的父类。 这些其他类如何获得mixin的方法取决于语言。 Mixin有时被描述为“包含”而不是“inheritance”。

具体来说,在像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(); 

我知道它是一个荒谬的例子,但是,它得到了重点…

TL;博士

mixin和多重inheritance具有相同的forms。 但是有不同的语义:mixin有基本的类提供函数的实现。 对于inheritance,基类提供的接口和子类都有实现。

但无论如何,组合优于混合IMO