抽象类、接口、mixins
有人可以向我解释一下抽象类、接口和mixins之间的区别吗? 我之前在代码中使用过它们,但我不知道技术差异。
Could someone please explain to me the differences between abstract classes, interfaces, and mixins? I've used each before in my code but I don't know the technical differences.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
抽象类
抽象类是不被设计为实例化的类。 抽象类可以没有实现、部分实现或全部实现。 抽象类旨在允许其子类共享公共(默认)实现。 抽象类的(伪编码)示例如下
所示 子类可能看起来像
可能的用法
如果子类不重写未实现的方法,那么它也是一个抽象类。
接口
在一般计算机科学术语中,接口是暴露给客户端的程序的一部分。 公共类和成员是接口的示例。
Java 和 C# 有一个特殊的
interface
关键字。 这些或多或少是一个没有实现的抽象类。 (常量、嵌套类、显式实现和访问修饰符有些棘手,我不打算深入讨论。)尽管“无实现”部分不再适合 Java,但他们添加了默认方法。interface
关键字可以看作是接口概念的具体化。回到 Shape 示例,
Java 和 C# 不允许具有实现的类的多重继承,但它们确实允许多个接口实现。 Java 和 C# 使用接口来解决以下语言中发现的致命钻石死亡问题允许多重继承(如果处理得当,这并不是那么致命)。
Mixin
Mixin(有时称为特征)允许抽象类的多重继承。 Mixin 没有多重继承所具有的可怕关联(由于 C++ 的疯狂),因此人们更愿意使用它们。 它们具有完全相同的致命钻石死亡问题,但支持它们的语言比 C++ 拥有更优雅的缓解方法,因此它们被认为更好。
Mixin 被誉为具有行为重用的接口, 更灵活接口,和更强大的界面。 您会注意到所有这些都包含术语
interface
,指的是Java 和C# 关键字。 Mixin 不是接口。它们是多重继承。 有了一个更漂亮的名字。这并不是说 mixin 不好。 多重继承并不坏。 C++ 解决多重继承的方式是每个人都兴奋不已的问题。
继续看陈旧的 Shape 示例,
您会发现这与抽象类示例没有区别。
额外的一点是,C# 从 3.0 版本开始就支持 mixin。 您可以使用接口上的扩展方法来完成此操作。 这是具有真实(!)C# 代码 mixin 风格的 Shape 示例
Abstract Class
An abstract class is a class that is not designed to be instantiated. Abstract classes can have no implementation, some implementation, or all implementation. Abstract classes are designed to allow its subclasses share a common (default) implementation. A (pseudocoded) example of an abstract class would be something like this
A subclass might look like
Possible usage
If a subclass does not override unimplemented methods, it is also an abstract class.
Interface
In general computer science terms, an interface is the parts of a program exposed to a client. Public classes and members are examples of interfaces.
Java and C# have a special
interface
keyword. These are more or less an abstract class with no implementation. (There's trickiness about constants, nested classes, explicit implementation, and access modifiers that I'm not going to get into.) Though the part about "no implementation" doesn't fit any more in Java, they added default methods. Theinterface
keyword can be seen as a reification of the interface concept.Going back to the Shape example
Java and C# do not allow multiple inheritance of classes with implementation, but they do allow multiple interface implementation. Java and C# use interfaces as a workaround to the Deadly Diamond of Death Problem found in languages that allow multiple inheritance (which isn't really that deadly, if properly handled).
Mixin
A mixin (sometimes called a trait) allows multiple inheritance of abstract classes. Mixins don't have the scary association that multiple inheritance has (due to C++ craziness), so people are more comfortable using them. They have the same exact Deadly Diamond of Death Problem, but languages that support them have more elegant ways of mitigating it than C++ has, so they're perceived as better.
Mixins are hailed as interfaces with behavioral reuse, more flexible interfaces, and more powerful interfaces. You will notice all these have the term
interface
in them, referring to the Java and C# keyword. Mixins are not interfaces. They are multiple inheritance. With a prettier name.This is not to say that mixins are bad. Multiple inheritance isn't bad. The way C++ resolves multiple inheritance is what everyone gets all worked up about.
On to the tired, old Shape example
You will notice there is no difference between this and the abstract class example.
One extra tidbit is that C# has supported mixins since version 3.0. You can do it with extension methods on interfaces. Here's the Shape example with real(!) C# code mixin style
一般来说:
接口是一个指定操作的契约,但没有任何实现。 某些语言(Java、C#)内置了对接口的支持,而在其他语言中,“接口”描述了一种约定,如 C++ 中的纯虚拟类。
抽象类是一种指定至少一个操作但没有实现的类。 抽象类还可以提供其实现的某些部分。 同样,某些语言内置了对将类标记为抽象的支持,而在其他语言中它是隐式的。 例如,在 C++ 中,定义纯虚方法的类是抽象的。
mixin 是一个类,其设计目的是使子类中某些功能的实现变得更容易,但其本身并不设计为使用。 例如,假设我们有一个处理请求的对象的接口,
也许通过累积请求来缓冲请求直到我们有一些预定的数量,然后刷新缓冲区会很有用。 我们可以使用 mixin 实现缓冲功能,而不需要指定刷新行为:
这样,我们就可以轻松编写一个请求处理程序,将请求写入磁盘、调用 Web 服务等,而无需重写每次都缓冲功能。 这些请求处理程序可以简单地扩展
BufferedRequestHandlerMixin
并实现flushBuffer
。mixin 的另一个很好的例子是 Spring 中的众多支持类之一,即。 HibernateDaoSupport 。
In general:
An interface is a contract specifying operations, but without any implementation. Some languages (Java, C#) have baked-in support for interfaces, and in others 'interface' describes a convention like a pure virtual class in C++.
An abstract class is a class which specifies at least one operation without an implementation. Abstract classes can also provide some parts of their implementation. Again, some languages have baked-in support for marking classes as abstract and it is implicit in others. For example, in C++ a class which defines a pure virtual method is abstract.
A mixin is a class which is designed to make implementation of certain functionality easier in subclasses, but which is not designed to be used by itself. For example, say that we have an interface for an object that handles requests
Perhaps it would be useful to buffer the requests by accumulating them until we have some predetermined number and then flushing the buffer. We can implement the buffering functionality with a mixin without specifying the flush behavior:
This way, it's easy for us to write a request handler that writes requests to disk, calls a web service, etc. without rewriting the buffering functionality each time. These request handlers can simply extend
BufferedRequestHandlerMixin
and implementflushBuffer
.Another good example of a mixin is one of the many support classes in Spring, viz. HibernateDaoSupport.
由于许多人已经解释了定义和用法,我只想强调重要的一点
接口:
具有
”功能。抽象类:
在几个密切相关的类之间共享代码。 它建立了“
is a
”关系。在相关类之间共享公共状态(可以在具体类中修改状态)
我用一个小例子来结束差异。
Animal
可以是一个抽象类。Cat
和Dog
,扩展这个抽象类建立了“is a
”关系。猫
是一种
动物狗
是一种
动物。Dog
可以
实现Bark
接口。 那么狗具有
吠叫的能力。Cat
可以
实现Hunt
接口。 那么猫具有
狩猎的能力。人,
不是动物
,可以实现Hunt
接口。 那么人类就有了狩猎的能力。人与动物(猫/狗)没有关系。 但Hunt接口可以为不相关的实体提供相同的能力。
Mixin:
抽象类
和接口
的混合。 当您想要在许多不相关的类上强制执行新契约时特别有用,其中一些类必须重新定义新行为,而其中一些应该坚持通用实现。 在 Mixin 中添加通用实现,并允许其他类在需要时重新定义契约方法。如果我想声明一个抽象类,我将遵循这两种方法之一。
将所有抽象方法移至
接口
,我的抽象类实现该接口。相关SE问题:
有什么区别接口和抽象类之间?
Since many of guys have explained about the definitions and usage, I would like to highlight only important points
Interface:
has a
" capabilities.Abstract class:
Share code among several closely related classes. It establishes "
is a
" relation.Share common state among related classes ( state can be modified in concrete classes)
I am closing the difference with a small example.
Animal
can be an abstract class.Cat
andDog
, extending this abstract class establishes "is a
" relation.Cat
is a
AnimalDog
is a
Animal.Dog
can
implementBark
interface. Then Doghas a
capability of Barking.Cat
can
implementHunt
interface. Then Cathas a
capability of Hunting.Man, who is
not Animal
, can implementHunt
interface. Then Manhas a
capability of Hunting.Man and Animal (Cat/Dog) are unrelated. But Hunt interface can provide same capability to unrelated entities.
Mixin:
abstract class
andinterface
. Especially useful when you want to force a new contract on many unrelated classes where some of them have to re-define new behaviour and some of them should stick to common implementation. Add common implementation in Mixin and allow other classes to re-define the contract methods if neededIf I want to declare an abstract class, I will follow one of these two approaches.
Move all abstract methods to
interface
and my abstract class implements that interface.Related SE question :
What is the difference between an interface and abstract class?
对 Java 的引用以及提供 mixin 的抽象类示例具有误导性。
首先,Java默认不支持“mixins”。 在 Java 术语中,抽象类和 Mixins 变得令人困惑。
mixin 是类除了其“主要类型”之外还可以实现的一种类型,以指示它提供一些可选行为。 用 Java 术语来说,一个例子是实现可序列化的业务价值对象。
Josh Bloch 说 - “抽象类不能用于定义 mixins - 因为一个类不能有多个父类”(记住 Java 只允许一个“扩展”候选者)
寻找 Scala 和 Ruby 等语言来适当实现这一概念“混合”的
Reference to Java and given example of Abstract class to provide mixin is misleading.
First of all, Java does not support "mixins" by default. In Java terms abstract class and Mixins become confusing.
A mixin is a type that a class can implement in addition to its "primary type" to indicate that it provides some optional behavior. To speak in Java terms, one example would be your business value object implementing Serializable.
Josh Bloch says - "Abstract classes can not be used to define mixins - since a class can not have more than one parent" ( Remember Java allows only one "extends" candidate)
Look for languages like Scala and Ruby for appropriate implementation of the notion of "mixin"
Joshua Bloch 在他的 Java 著作中对“Mixin”的含义进行了出色的定义。 同一本书的摘录:
“mixin 是一种类型
除了其“主要类型”之外,类还可以实现以声明它提供
一些可选的行为。 例如,Comparable 是一个 mixin 接口,
允许一个类声明其实例相对于其他实例是相互排序的
可比较的对象。 这样的接口称为 mixin,因为它允许
要“混合”到类型的主要功能中的可选功能。”
The meaning of 'Mixin' is excellently defined by Joshua Bloch in his effective Java book. An excerpt from the same book:
"mixin is a type
that a class can implement in addition to its “primary type” to declare that it provides
some optional behavior. For example, Comparable is a mixin interface that
allows a class to declare that its instances are ordered with respect to other mutually
comparable objects. Such an interface is called a mixin because it allows the
optional functionality to be “mixed in” to the type’s primary functionality."
基本上,抽象类是具有一些具体实现的接口。 接口只是一个没有实现细节的契约。
如果您想在实现抽象类的所有对象之间创建通用功能,则可以使用抽象类。 遵守 OOP 的 DRY(不要重复自己)原则。
Basically an abstract class is an interface with some concrete implementation. An interface is just a contract that has no implementation detail.
You would use and abstract class if you want to create common functionality amoung all of the objects that implement the abstract class. Keeping with the DRY (Don't Repeat Yourself) principle of OOP.
抽象类是一个类,它的所有成员都没有被实现,它们留给继承者去实现。它强制它的继承者实现它的抽象成员。
抽象类不能实例化,因此它们的构造函数不应该是公共的。]
这是 C# 中的一个示例:
}
接口是由类实现的契约。它只是声明实现类的成员的签名,并且它本身没有实现。我们通常使用接口来实现多态性,并解耦依赖的类。
下面是一个 C# 示例:
An abstract class is a class that not all of its members are implemented ,they are left for the inheritors to be implemented.It forces its inheritors to implement its abstract members.
Abstract classes can't be instantiated and thus their constructors shouldn't be public.]
Here's an example in C#:
}
An interface is a contract to be implemented by a class.It just declare the signature of the members of an implementing class and it has no implementation itself.We usually use interfaces to implement polymorphism,and to decouple dependent classes.
Here's an example in C#: