为什么我们需要Scala中的特质? [英] Why do we need traits in scala?
问题描述
所以,我试图制作一个 finagle 服务器,与哨兵交谈(不重要),并偶然发现了一个案例,我需要同时从两个类(不是特征)继承时间,让我们称它们为 class SentryHandler extends Handler
和 class TwitterHandler extends Handler
,并假设我需要创建 MyHandler
,它继承自两者其中.
So, I was trying to make a finagle server, talk to sentry (not important), and stumbled upon a case, where I needed to inherit from two classes (not traits) at the same time, let's call them class SentryHandler extends Handler
and class TwitterHandler extends Handler
, and assume, that I need to create MyHandler
, that inherits from both of them.
愚蠢的片刻之后,当我认为不使用可怕的委托模式"是不可能的时,我找到了一个解决方案:
After a moment of stupidity, when I thought it was impossible without using a dreaded "delegation pattern", I found a solution:
trait SentryTrait extends SentryHandler
class MyHandler extends TwitterHandler with SentryTrait
现在,这让我思考:拥有特质"概念的目的是什么?如果这个想法是强制您可以从多个特征继承,但只能从一个类继承,那么绕过似乎非常容易.听起来好像 class
应该是继承的主要"线(你扩展一个具有特征的类",但是也不是真的:您可以扩展
带有(或不带有)一堆其他特征的特征,而根本没有类.
Now, this got me thinking: what is the purpose of having the notion of "trait" to being with? If the idea was to enforce that you can inherit from multiple traits but only a single class, it seems awfully easy to get around. It kinda sounds like class
is supposed to be the "main" line of inheritance (that you "extend a class with traits", but that isn't true either: you can extend
a trait with (or without) a bunch of other traits, and no class at all.
你不能实例化一个特征,但同样适用于抽象类......
You cannot instantiate a trait, but the same holds for an abstract class ...
我能想到的唯一真正的区别是特征不能有构造函数参数.但这有什么意义呢?我的意思是,为什么不呢?这样的事情会有什么问题?
The only real difference I can think of is that a trait cannot have constructor parameters. But what is the significance of that? I mean, why not? What would the problem with something like this?
class Foo(bar: String, baz: String) extends Bar(bar) with Baz(baz)
推荐答案
您的解决方案(如果我理解正确的话) - 不起作用.你不能在 Scala 中多重继承类:
Your solution (if I understood correctly) - doesn't work. You cannot multiinherit classes in scala:
scala> class Handler
defined class Handler
scala> class SentryHandler extends Handler
defined class SentryHandler
scala> class TwitterHandler extends Handler
defined class TwitterHandler
scala> trait SentryTrait extends SentryHandler
defined trait SentryTrait
scala> class MyHandler extends TwitterHandler with SentryTrait
<console>:11: error: illegal inheritance; superclass TwitterHandler
is not a subclass of the superclass SentryHandler
of the mixin trait SentryTrait
class MyHandler extends TwitterHandler with SentryTrait
至于问题 - 为什么是traits,在我看来,这是因为traits 是可堆叠的,以解决著名的钻石问题
As for the question - why traits, as I see it, this is because traits are stackable in order to solve the famous diamond problem
trait Base { def x: Unit = () }
trait A extends Base { override def x: Unit = { println("A"); super.x}}
trait B extends Base { override def x: Unit = { println("B"); super.x}}
class T1 extends A with B {}
class T2 extends B with A {}
(new T1).x // Outputs B then A
(new T2).x // Outputs A then B
即使特征 A
super 是 Base
(对于 T1
)它调用 B
实现而不是 基础代码>.这是由于特质线性化
Even though trait A
super is Base
(for T1
) it calls B
implementation rather then Base
. This is due to trait linearization
因此,对于类,如果您扩展某些东西 - 您可以确定接下来将调用此基类.但对于特质而言,情况并非如此.这可能就是你没有 trait 构造函数参数的原因
So for classes if you extend something - you can be sure that this base will be called next. But this is not true for traits. And that's probably why you do not have trait constructor parameters
这篇关于为什么我们需要Scala中的特质?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!