所以,我试图制作一个 Finagle 服务器,与哨兵交谈(不重要),并偶然发现了一个案例,我需要从两个继承classes(不是特质)同时,我们称它们为class SentryHandler extends Handler
and class TwitterHandler extends Handler
,并假设我需要创建MyHandler
,继承自他们两者。
经过一阵愚蠢之后,当我认为不使用可怕的“委托模式”就不可能时,我找到了一个解决方案:
trait SentryTrait extends SentryHandler
class MyHandler extends TwitterHandler with SentryTrait
现在,这让我思考:拥有“特质”这一概念的目的是什么?如果这个想法是强制您可以从多个特征继承,但只能从一个类继承,那么似乎很容易解决。听起来有点像class
应该是继承的“主”线(你“extend一类with特征”,但这也不是真的:你可以extend
具有(或不具有)一堆其他特征的特征,并且根本没有阶级。
您无法实例化特征,但抽象类也是如此......
我能想到的唯一真正的区别是特征不能有构造函数参数。但这有什么意义呢?
我的意思是,为什么不呢?这样的事情会出现什么问题呢?
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
至于问题 - 为什么特征,在我看来,这是因为特征是可以堆叠的,以解决著名的问题钻石问题 https://en.wikipedia.org/wiki/Multiple_inheritance#The_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
超级是Base
(for T1
)它调用B
实施而不是Base
。这是因为特征线性化 https://stackoverflow.com/questions/34242536/linearization-order-in-scala
因此,对于类来说,如果您扩展某些内容 - 您可以确定接下来将调用该基类。但对于特质来说却并非如此。这可能就是为什么你没有特征构造函数参数的原因
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)