【问题标题】:Is possible to override private val in scala trait可以覆盖 scala trait 中的私有 val
【发布时间】:2015-04-19 18:41:21
【问题描述】:

我必须测试包含私有 val 的 trait,但是这个 val 需要被覆盖以测试提议。

trait A {
  private val someVariable = 0
}

测试类

@RunWith(classOf[JUnitRunner]) class ATest extends FunSuite {
  val a = new A{
    override private val someVariable = 1 
  }

  test("test of someVariable ){
    assert(a.someVariable == 1) //I know that I can't print private variable in this way, but it is just for showing what I need.
  }

} 

这里有什么方法可以覆盖这个变量吗? 谢谢

【问题讨论】:

  • 为什么不定义为protected
  • 我无法更改封装。

标签: scala


【解决方案1】:

特征初始化器还需要设置该字段,因此您可以利用该公共合成设置器:

scala> :pa -raw
// Entering paste mode (ctrl-D to finish)

package XX { trait X { private val x = 42 ; def test = x * 2 } }

// Exiting paste mode, now interpreting.


scala> (new XX.X {}).test
res0: Int = 84

scala> val v = new XX.X {}
v: XX.X = $anon$1@3cd1f1c8

scala> classOf[XX.X].getDeclaredMethod("XX$X$_setter_$XX$X$$x_$eq", classOf[Int])
res1: java.lang.reflect.Method = public abstract void XX.X.XX$X$_setter_$XX$X$$x_$eq(int)

scala> res1.invoke(v, 3: Integer)
res2: Object = null

scala> v.test
res3: Int = 6

反射性剥猫皮的方法不止一种。

【讨论】:

  • 如果在初始化过程中急切地使用该值,那就没有用了。
【解决方案2】:

我将我的特质修改为

trait A {
  private[package] val someVariable = 0
}

现在可以了。

【讨论】:

  • 为什么评论说你不能改变封装,你最终做了什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
  • 2011-09-07
  • 2018-03-15
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
相关资源
最近更新 更多