为什么我们需要Scala中的特质?

Dim*_*ima 5 scala traits

所以,我试图制作一个 finagle 服务器,与哨兵交谈(不重要),并偶然发现了一个案例,我需要同时从两个(不是特征)继承,让我们称它们为class SentryHandler extends Handlerand class TwitterHandler extends Handler,并假设,我需要创建MyHandler,从他们两个继承。

在愚蠢的片刻之后,当我认为不使用可怕的“委托模式”是不可能的时,我找到了一个解决方案:

trait SentryTrait extends SentryHandler
class MyHandler extends TwitterHandler with SentryTrait
Run Code Online (Sandbox Code Playgroud)

现在,这让我思考:拥有“特质”概念的目的是什么?如果这个想法是强制您可以从多个特征继承,但只能从一个类继承,那么绕过似乎非常容易。听起来class应该是继承的“主要”线(您“扩展具有特征的类”,但这也不是真的:您可以extend将特征带(或不带)一堆其他特征,并且根本没有课。

你不能实例化一个特征,但同样适用于抽象类......

我能想到的唯一真正的区别是特征不能有构造函数参数。但这有什么意义呢?我的意思是,为什么不呢?这样的事情会有什么问题?

class Foo(bar: String, baz: String) extends Bar(bar) with Baz(baz) 
Run Code Online (Sandbox Code Playgroud)

Arc*_*heg 6

您的解决方案(如果我理解正确的话)- 不起作用。你不能在 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
Run Code Online (Sandbox Code Playgroud)

至于问题——为什么是特质,在我看来,这是因为特质是可以叠加的,以解决著名的钻石问题

  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
Run Code Online (Sandbox Code Playgroud)

尽管 trait Asuper 是Base(for T1) 它调用Bimplementation 而不是Base。这是由于特征线性化

所以对于类,如果你扩展了一些东西——你可以确定接下来会调用这个基类。但对于特质而言,情况并非如此。这可能就是你没有 trait 构造函数参数的原因