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

Scala可堆叠的特征

发布时间:2020-12-16 19:13:11 所属栏目:安全 来源:网络整理
导读:对于下面的代码,因为我理解它的表达式的线性化 新的E与D与C与B 是E – C – B – D.那么在代码中不应该使用表达式d.foo() 下面评估ECBD而不是CBDE.我错过了什么? trait A { def foo(): String = "" } trait B extends A { abstract override def foo() = "B
对于下面的代码,因为我理解它的表达式的线性化

新的E与D与C与B

是E – > C – > B – > D.那么在代码中不应该使用表达式d.foo()

下面评估ECBD而不是CBDE.我错过了什么?

trait A {
      def foo(): String = ""
    }

    trait B extends A {
      abstract override def foo() = "B" + super.foo()
    }

    trait C extends B {
      abstract override def foo() = "C" + super.foo()
    }

    trait D extends A {
      abstract override def foo() = "D" + super.foo()
    }

    class E extends A{
      override def foo() = "E"
    }

    var d = new E with D with C with B;
    d.foo() //prints CBDE

我注意到如果我有一个类F如下

class F extends A with D with C with B{
      override def foo() = "F" + super.foo()
}

并做

new F().foo

它打印“FCBD”

这对我来说似乎有些不一致,因为类F的混合方式与表达式相同但具有不同的打印顺序

解决方法

新的E与D与C与B的第一个案例完美地解释了 here.它的线性化是EDBC,所以当你调用d.foo()时,它

>首先调用C#foo(),
>那么B#foo(),
>然后D#foo()
>最后是E#foo().

如果你把E作为一个特征并在最后混合它:val d = new D with C with B with E,那么d.foo()将只返回“E”,因为trait E是线性化中的“last”和只是覆盖了.

F的情况是不同的,因为你将foo定义为“F”super.foo(),而在这种情况下super是A与D与C与B的线性化是ADBC,所以新的F().foo()
– 首先打印“F”,
– 然后它的super.foo()是“CBD”.

顺便说一下,尝试更改A#foo()以返回“A”,然后您将看到在E中覆盖A的foo,因此“A”不会出现在结果中,而在F中它是“FCBDA”.

(编辑:李大同)

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

    推荐文章
      热点阅读