|
|
1
833
作为一个例子,考虑一下 werkzeug's request and response system . 我可以通过以下方式创建一个普通的旧请求对象:
如果我想添加accept标头支持,我会这样做
如果我想创建一个支持accept标头、ETag、身份验证和用户代理支持的请求对象,我可以这样做:
区别很微妙,但在上面的例子中,mixin类并不是独立存在的。在更传统的多重继承中
|
|
|
2
272
基本上,mixin是一个独立的基类,它为子类提供有限的功能和多态共振。如果你想用C#,想想一个你不需要实际实现的接口,因为它已经实现了;您只是继承了它,并从它的功能中受益。 mixin的范围通常很窄,不打算扩展。
既然你问了,我想我应该谈谈原因。最大的好处是你不必一次又一次地自己做。在C#中,混搭的最大好处可能是 Disposal pattern . 无论何时实现IDisposable,您几乎总是希望遵循相同的模式,但最终编写并重新编写相同的基本代码,只是略有变化。如果有一个可扩展的处理混入,你可以节省大量额外的打字。 [编辑2——回答您的其他问题]
对mixin和标准多重继承之间的区别只是语义问题;具有多重继承的类可以使用mixin作为多重继承的一部分。 mixin的要点是创建一个可以通过继承“混合”到任何其他类型的类型,而不影响继承类型,同时仍然为该类型提供一些有益的功能。 同样,考虑一个已经实现的接口。 我个人不使用mixin,因为我主要是用一种不支持mixin的语言开发的,所以我很难想出一个像样的例子来为您提供“啊哈!”的时刻。但我会再试一次。我将使用一个精心设计的示例——大多数语言已经以某种方式提供了该特性——但希望这能解释如何创建和使用mixin。下面是: 假设您有一个类型,希望能够在XML之间序列化。您希望该类型提供一个“ToXML”方法,该方法返回包含该类型数据值的XML片段的字符串,以及一个“FromXML”方法,该方法允许该类型从字符串中的XML片段重构其数据值。同样,这是一个人为的示例,所以您可能会使用一个文件流,或者您的语言的运行库中的XML编写器类。。。无论什么关键是要将对象序列化为XML,并从XML中获取新对象。 本例中的另一个要点是,您希望以通用的方式执行此操作。您不需要为每个要序列化的类型实现“ToXML”和“FromXML”方法,您需要一些通用的方法来确保您的类型能够做到这一点,并且它能够正常工作。您需要代码重用。 如果您的语言支持它,您可以创建XmlSerializable mixin来为您完成工作。这种类型将实现ToXML和FromXML方法。它将使用一些对示例不重要的机制,能够从任何类型收集所有必要的数据,这些数据与ToXML混合在一起,以构建ToXML返回的XML片段,并且在调用FromXML时同样能够恢复这些数据。 和就这样。要使用它,您需要将任何需要序列化为XML的类型从XmlSerializable继承。每当需要序列化或反序列化该类型时,只需调用ToXML或FromXML。事实上,由于XmlSerializable是一种成熟的类型和多态性,可以想象,您可以构建一个文档序列化程序,它对原始类型一无所知,只接受(比如)一个XmlSerializable类型数组。 现在想象一下,将此场景用于其他事情,比如创建一个mixin,确保每个混合它的类都记录每个方法调用,或者创建一个mixin,为混合它的类型提供事务性。这个名单可以一直列下去。 如果您只是将mixin看作是一个小的基本类型,它旨在向一个类型添加少量功能,而不影响该类型,那么您就是黄金。 希望如此。:) |
|
|
3
214
这个答案的目的是解释混音 举例说明 它们是:
还应考虑有争议的问题:
定义
定义1:没有多重继承 mixin是这样一个类:该类的某个方法使用该类中未定义的方法。 因此,该类不是要被实例化,而是作为基类使用。否则,实例将具有在不引发异常的情况下无法调用的方法。 一些源添加的一个约束是类可能不包含数据,只包含方法,但我不明白为什么这是必要的。然而,在实践中,许多有用的mixin没有任何数据,没有数据的基类更易于使用。
一个典型的示例是仅从中实现所有比较运算符
这个特殊的例子可以通过
定义2:多重继承 mixin是一种设计模式,其中基类的某个方法使用它未定义的方法,并且该方法将由 另一个基类 术语 混合班 指打算在该设计模式中使用的基类(是指使用该方法的基类,还是指实现该方法的基类?)
权威Python事件 在 official documentatiton for collections.abc 文档中明确使用了这个术语 混合方法 . 它指出,如果一个类:
然后全班都会得到一个
因此,至少在文件的这一点上, ,并与定义1一致。 当然,文档在不同的点上可能相互矛盾,其他重要的Python库可能在文档中使用其他定义。
本页还使用术语
用其他语言
|
|
|
4
42
我认为它们是使用多重继承的一种严格方法,因为最终mixin只是另一个python类,它(可能)遵循关于称为mixin的类的约定。 我对管理你称之为Mixin的事物的约定的理解是,Mixin:
这样一来,它就限制了多重继承的潜在复杂性,并通过限制必须查看的位置(与完全多重继承相比),使跟踪程序流变得相当容易。它们类似于 ruby modules . 如果我想添加实例变量(比单一继承更灵活),那么我倾向于组合。
|
|
5
36
特别是在Python上下文中,mixin是一个父类,它为子类提供功能,但不打算自己实例化。 您可能会说,“这只是多重继承,不是真正的mixin”,是因为可能会被混淆为mixin的类实际上可以被实例化和使用——因此它确实是一个语义上的、非常真实的差异。 多重继承的例子
它将两个
二者都
这是一种强大的重用代码的方法,但也可能有问题。如果发现其中一个对象中有一个bug,不小心修复它可能会在子类中创建一个bug。 Mixin示例
与上面的示例不同,mixin不打算单独使用。它提供了新的或不同的功能。
例如,标准库有两个
mixins in the
在本例中,mixin方法覆盖
重写的方法似乎是
做作的例子
其用途是:
使用方法:
|
|
|
6
30
mixin是编程中的一个概念,其中类提供功能,但并不用于实例化。mixin的主要目的是提供独立的功能,如果mixin本身没有与其他mixin的继承,并且避免状态,则最好是这样。在Ruby等语言中,有一些直接的语言支持,但对于Python则没有。但是,您可以使用多类继承来执行Python中提供的功能。 我看了这个视频 http://www.youtube.com/watch?v=v_uKI2NOLEM 维基百科仍然是最好的: http://en.wikipedia.org/wiki/Mixin |
|
|
7
19
我认为之前的回答很好地定义了什么 混血儿 是然而 为了更好地理解它们,比较可能是有用的 混血儿 具有 抽象类 和 接口 从代码/实现的角度来看: 1.抽象类
2.界面
3.混血儿
|
|
|
8
11
我认为这里有一些很好的解释,但我想提供另一个视角。 在Scala中,您可以像这里所描述的那样进行混合,但非常有趣的是,这些混合实际上是“融合”在一起的,以创建一种新的类来继承。本质上,您不会从多个类/mixin继承,而是生成一个新的类,该类包含要从中继承的mixin的所有属性。这是有意义的,因为Scala基于JVM,目前不支持多重继承(从Java8开始)。顺便说一下,这个mixin类类型是Scala中称为Trait的特殊类型。 它以类的定义方式暗示: ... 我不确定CPython解释器是否也执行相同的操作(mixin类组合),但我不会感到惊讶。另外,从C++背景来看,我不把ABC或“接口”称为混合函数——它是一个类似的概念,但在使用和实现上是不同的。 |
|
|
9
9
我建议不要在新的Python代码中混入,如果你能找到其他的解决方法(比如组合而不是继承,或者只是在你自己的类中使用猴子补丁方法),那就不用花太多精力了。
在旧式类中,可以使用mix-ins作为从另一个类中获取一些方法的方法。但在新风格的世界里,一切东西,甚至是混合在一起的东西,都继承自
有一些方法可以使多继承MRO在Python中工作,最著名的是super()函数,但这意味着必须使用super()来完成整个类层次结构,并且理解控制流要困难得多。 |
|
|
10
9
也许几个例子会有所帮助。
如果您正在构建一个类,并且希望它像字典一样工作,那么您可以定义所有不同的
|
|
|
11
9
the D programing language
在D中(顺便说一句,它不做MI),这是通过在范围中插入一个模板来完成的(想想语法感知和安全的宏,你会很接近的)。这允许类、结构、函数、模块或任何东西中的一行代码扩展到任意数量的声明。 |
|
|
12
7
OP提到他/她在C++中从未听说过MIXIN,也许是因为C++中的奇怪的模板模式(CRTP)。此外,Ciro Santilli提到MIXIN是通过C++中的抽象基类实现的。虽然抽象基类可以用来实现mixin,但这是一种过分的做法,因为运行时虚拟函数的功能可以在编译时使用模板实现,而不会在运行时产生虚拟表查找的开销。 我使用下面的模板类将@ Ciro Santilli的答案中的Python示例转换成C++。
编辑:在ComparableMixin中添加了受保护的构造函数,因此它只能被继承而不能实例化。更新了示例,以显示创建ComparableMixin对象时受保护构造函数将如何导致编译错误。 |
|
|
13
6
也许ruby的一个例子可以帮助:
你可以把调味品包括在内
它通过调用
|
|
|
14
6
mixin提供了一种在类中添加功能的方法,也就是说,您可以通过将模块包含在所需的类中来与模块中定义的方法进行交互。虽然ruby不支持多重继承,但提供了mixin作为实现多重继承的替代方案。 下面的示例说明了如何使用mixin实现多重继承。
|
|
|
15
6
我刚刚使用了一个pythonmixin来实现pythonmilter的单元测试。通常,milter会与MTA对话,这使得单元测试变得困难。测试mixin覆盖与MTA对话的方法,并创建由测试用例驱动的模拟环境。 因此,我们使用未经修改的milter应用程序,如spfmilter和mixin TestBase,如下所示:
然后,在milter应用程序的测试用例中使用TestMilter:
http://pymilter.cvs.sourceforge.net/viewvc/pymilter/pymilter/Milter/test.py?revision=1.6&view=markup |
|
|
16
3
您可能希望在以下位置查看codeplex项目: http://remix.codeplex.com/ 观看lang.net专题讨论会链接以获得概述。codeplex页面上的文档还有更多内容。 当做 斯特凡 |