因此,我试图制作一个固定服务器,与哨兵交谈(不重要),偶然发现了一个案例,在该案例中,我需要同时继承两个类(而不是特征),我们将它们分别称为class SentryHandler extends Handler
和class 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因此,对于类,如果您扩展了某些内容,则可以确保下一步将调用此基础。但这对特质而言并非如此。这可能就是为什么您没有特征构造函数参数的原因