加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 堆叠特征中super的含义取决于呼叫站点?

发布时间:2020-12-16 08:45:03 所属栏目:安全 来源:网络整理
导读:我无法用语言对此进行非常好的描述,所以,请看一下这个例子: trait Base { def foo = "Base" }trait One extends Base { override def foo = "One : " + super.foo }trait Two extends Base { override def foo = "Two : " + super.foo }new Base with One w
我无法用语言对此进行非常好的描述,所以,请看一下这个例子:

trait Base { def foo = "Base" }
trait One extends Base { override def foo = "One <: " + super.foo }
trait Two extends Base { override def foo = "Two <: " + super.foo }

new Base with One with Two {} foo

这打印:两个<:One&lt ;: Base,这是我所期待的.
现在,我正在尝试添加另一个级别,以便覆盖的特征不必显式调用super.像这样:

trait Base { def foo = "Base" }
trait Foo extends Base { def bar = foo + " <: " + super.foo }
trait One extends Foo { override def foo = "One" }
trait Two extends Foo { override def foo = "Two" }

new Foo with One with Two {} bar

这里,最后一行打印出两个&lt ;: Base

因此,在第一个例子中看起来像super表示One,而在最后一个示例中它跳过One并直接转到Base.

为什么会这样?不应该是一样的行为吗?

解决方法

在第一种情况下,新的Base with One with Two {} foo(与新的One with two {} foo相同),“trait stack”非常明显. Two有一个foo,它调用超级(One)的foo,它调用超级(Base)的foo.

在第二种情况下,新的Foo与One with Two {} bar(与具有Two {} bar的新One相同),“trait stack”是Base-> Foo-> One-> Two.你打电话给酒吧,但是两个没有酒吧,一个没有酒吧. Foo有一个叫它super(Base)的foo的吧.

UPDATE

考虑@Dima提出的这个mod.

trait Base { def foo = "Base" }
trait Foo extends Base { def bar = foo + " <: " + super.foo }
trait One extends Foo { override def bar = super.bar
                        override def foo = "One" }
trait Two extends Foo { override def bar = super.bar
                        override def foo = "Two" }

new One with Two {} bar  // no Base or Foo needed

是的,这给出了与之前相同的输出:res0:String = Two<:Base 现在两个调用超级(One)的栏,它调用超级(Foo)的栏,调用其超级的foo(不是栏). 所有这些bar活动都与foo定义分开.两个从不调用它的超级foo,所以One.foo从未使用过,也不能成为输出的一部分. 一种不同的方法 考虑以下.

trait B { def id = "B" } // B for Base

trait V extends B { override def id = "V" }
trait W extends B { override def id = "W" }
trait X extends B { override def id = "X" }
trait Y extends B { override def id = "Y" }
trait Z extends B { override def id = "Z" }

trait R extends B { override def id = "R"; def mySup = super.id } // Required

现在尝试以多种不同的方式实例化它.

val r = new V with Y with W with R with X {} // B not needed
// or
val r = new W with R with Z with X with V {}
// or
val r = new R with Y with V with B with W {}
// or
val r = new Z with Y with X with W with R {}
// etc.

在每种情况下,r.id将是链中的最后一个特征,r.mySup将是R之前的特征(如果在R之前没有指定,则为B).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读