为什么我们需要Scala中的特质? [英] Why do we need traits in scala?

查看:49
本文介绍了为什么我们需要Scala中的特质?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我试图制作一个 finagle 服务器,与哨兵交谈(不重要),并偶然发现了一个案例,我需要同时从两个(不是特征)继承时间,让我们称它们为 class SentryHandler extends Handlerclass 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆