在Scala中,字段在主构造函数声明。 而且,如果它恰好具有相同的名称从超类中的字段,它将使用一个传入相反,这正是我想避免的。 看看下面的例子:
class Parent(protected val changedParam: MyClass)
class Child(changedParam: MyClass) extends Parent(doStuff(changedParam)) {
def foo() = {
bar(changedParam) // Uses Child.changedParam, not Parent.changedParam, which is what I want
}
}
我要让changedParam在孩子指changedParam在父,子不。 有没有办法做到这一点?
一类的参数是在它的身上看到。 该文件将在一个私人VAL如果需要的话,那就是如果它的方法中使用,而不是仅仅在初始化代码(当然,如果它没有直接声明为有不同的可见性,或VAR一VAL)。
所以changedParam
在Child
阴影的一个在Base
。 为了避免明显的方法是简单地调用它的另一个名字:
class Child(anotherName: MyClass) extends Base(doStuff(anotherName)) {...
这被认为是脆弱和愤怒。
你得到,如果你遮蔽一个变种稍有缓解:
scala> class A { var a = 1 } ; class B(a: Int) extends A { def f = a }
defined class A
defined class B
scala> val b = new B(42) ; b.a = 7 ; b.f
b: B = B@1376c05c
b.a: Int = 7
res0: Int = 42
scala> :replay -Xlint
Replaying: class A { var a = 1 } ; class B(a: Int) extends A { def f = a }
<console>:7: warning: private[this] value a in class B shadows mutable a inherited from class A. Changes to a will not be visible within class B - you may want to give them distinct names.
class A { var a = 1 } ; class B(a: Int) extends A { def f = a }
^
defined class A
defined class B
Replaying: val b = new B(42) ; b.a = 7 ; b.f
b: B = B@f2ff811
b.a: Int = 7
res0: Int = 42
通常情况下,一个阴影val为更加良性的,但你的例子警告将是有益的。
class Parent(protected val changedParam: MyClass)
trait Child extends Parent {
def foo() = {
bar(changedParam)
}
}
object Child {
def apply(changedParam: MyClass): Child =
new Parent(doStuff(changedParam)) with Child
}
不多说了......谈到Child
进入trait
避免了声明,你不希望在初始化后使用新的临时成员。 然后我用了同伴对象申报的构造。 在使用唯一的区别是,你不必在添加new
关键字来实例化Child
。
测试:
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Parent(protected val changedParam: Int)
trait Child extends Parent {
def foo() = {
println(changedParam)
}
}
object Child {
def apply(changedParam: Int): Child =
new Parent(1 + changedParam) with Child
}
// Exiting paste mode, now interpreting.
defined class Parent
defined trait Child
defined object Child
scala> Child(42).foo()
43
1)使用显式调用Parent
与asInstanceOf
:
package demo {
// remove protected or make it protected[demo]
class Parent(protected[demo] val changedParam: MyClass)
class Child(changedParam: MyClass)
extends Parent(doStuff(changedParam)) {
def foo() = {
bar(this.asInstanceOf[Parent].changedParam)
}
}
}
2)使用早期初始化的语法:
class Parent(protected val changedParam: MyClass)
class Child(changedParam: MyClass) extends {
val superChangedParam = doStuff(changedParam)
} with Parent(superChangedParam) {
def foo() = {
bar(superChangedParam)
}
}
尽管如此,最好的解决办法就是给不同的名称,以您的PARAM。