Mixin vs继承

时间:2009-05-13 20:31:56

标签: oop inheritance mixins

mixin和inheritance有什么区别?

9 个答案:

答案 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是继承的子集或特例。

使用混合而不是单一继承的优点是,您可以为函数编写一次代码,然后在多个不同的类中使用相同的功能。缺点是您可能需要在其他位置查找该功能,因此最好通过将其保持在附近来缓解该缺点。

我个人发现使用单一继承所需的混合,我们正在对许多类似的代码进行单元测试,但是测试用例是基于它们对基本情况的继承而实例化的,并且是保持测试用例的唯一方法。在没有弄乱覆盖号的情况下,代码就在眼前(并且在同一个模块中)是从对象继承的,并且子例子继承自通用测试用例库和仅适用于它们的自定义库。

Mixins in Comparison and Contrast with Abstract Base Classes

两者都是父类的一种形式,不打算实例化。

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世界中引起争议的语言构造:

  • 必须解决的含糊不清
  • 很多时候“ mixin”类不能单独工作,并且可能与其他mixins冲突
  • 这可能会导致“钻石继承问题”,其中两个超类可以从同一个类继承

但是,除此之外,它是一种强大的构造,可用于各种语言和框架,例如: