在学习
Scala时,我一直在努力理解一个特殊的细微差别:
特质测试
带测试的类Tester //#A:引发编译错误
class Tester扩展Test //#B:工作正常
现在,我们并没有真正扩展这个特性(或者我们是谁?).以下是我的问题:
>扩展特质与扩展课程有何不同?它只是一个单一特征的特殊情况语法,我只是接受它作为语言的细微差别?
>为什么#A不正确?我们为什么不能这样做?如果没有任何超级类继承,为什么我们必须扩展特征?
Martin Odersky在对similar question的回应中表示,这是大会,但人们发现它令人困惑.我不确定为什么会出现这种情况或者导致这一决定的问题是什么?但这是他的回答:
We had that convention early on in the design of Scala. People found
it confusing. That’s why we changed to use always `extends’. The way I
see it is like this:class A extends B with C { … }
should be decomposed as:
class A extends <<< B with C { … } >>>
That is, A is a class that extends the anonymous template B with C {
… }. It does not matter whether that template starts with a class or
a trait.Another advantage of the new convention is that subclasses are not
affected when a class is changed to a trait or vice versa, something
that happens quite often and naturally.
虽然我可以忍受他的解释并重新思考我的想法(并且看到将课程改为特质的优势,仅仅是设计选择的副作用),我仍然希望更直观地理解这种细微差别.
最佳答案 我可以向你展示一个例子,我觉得“扩展”特征的“概念”实际上是合乎逻辑的,
使用结构类型和自我引用特征的混合来查看以下代码,
type Fooable = {
def foo(): Unit
}
trait FooableExtra { self: Fooable =>
def omgWeCanFoo(): Unit = {
println("foo :: by :: FooableExtra")
self.foo()
}
}
class OneThingWithFoo extends FooableExtra {
def foo(): Unit = {
println("foo :: by :: OneThingWithFoo")
}
def oneThing: Unit = {}
}
我不能用语言来解释它,而且更直观一些……但是这就是让我在写A类扩展TraitA时有良心的原因.