因此,我试图制作一个固定服务器,与哨兵交谈(不重要),偶然发现了一个案例,在该案例中,我需要同时继承两个类(而不是特征),我们将它们分别称为class SentryHandler extends Handlerclass TwitterHandler extends Handler,假设我需要创建MyHandler,该继承自他们两个。

愚蠢的一会儿之后,当我认为如果不使用可怕的“委托(delegate)模式”是不可能的,我找到了一个解决方案:

trait SentryTrait extends SentryHandler
class MyHandler extends TwitterHandler with SentryTrait

现在,这让我开始思考:拥有“特质”这一概念的目的是什么?如果要强制您可以从多个特征继承而只能继承一个类,那么似乎很容易解决。听起来有点像class应该是继承的“主”行(您“用特质扩展类”,但这也不是正确的:您可以使用(或不带有)其他特质对一个特质进行extend。 ,而且完全没有类(class)。

您无法实例化特征,但是对于抽象类而言,情况同样如此……

我能想到的唯一真正的区别是特征不能具有构造函数参数。但是,这有什么意义呢?
我的意思是,为什么不呢?这样的问题会是什么问题?
class Foo(bar: String, baz: String) extends Bar(bar) with Baz(baz)

最佳答案

您的解决方案(如果我理解正确的话)-不起作用。您无法在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

至于问题-为什么特质,如我所见,这是因为特质可堆叠以解决著名的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

即使trait A super是Base(对于T1),它也会调用B实现而不是Base。这是由于trait linearization

因此,对于类,如果您扩展了某些内容,则可以确保下一步将调用此基础。但这对特质而言并非如此。这可能就是为什么您没有特征构造函数参数的原因

10-07 17:08