我想实例化一个特征并覆盖受保护的函数 g ,使其可访问(函数 f 用于测试)。
trait A {
protected def g( i: Int ) = println( i )
def f( i: Int ) = println( i )
}
我创建了一个对象a1
val a1= new A {
override def f( i: Int ) = super.f(i)
override def g( i: Int ) = super.g(i)
def h( i: Int ) = super.g(i)
}
并尝试调用方法
a1.f(1)
a1.g(3) // this call fails
a1.h(5)
对于 a1.g(3),我收到此错误:
<console>:10: error: method g in trait A cannot be accessed in A{def h(i: Int): Unit}
Access to protected method g not permitted because
enclosing object $iw is not a subclass of
trait A where target is defined
a1.g(3) // this call fails
但是当我定义一个特征 A2 扩展 A 并覆盖方法 f 和 g 时,创建一个它的实例并调用方法,一切正常
trait A2 extends A {
override def f( i: Int ) = super.f(i)
override def g( i: Int ) = super.g(i)
def h( i: Int ) = super.g(i)
}
val a2= new A2 {}
a2.f(2)
a2.g(4)
a2.h(6)
为什么
之间存在差异val a1= new A {
override def g( i: Int ) = super.g(i)
}
和
trait A2 extends A {
override def g( i: Int ) = super.g(i)
}
val a2= new A2 {}
谢谢!
答案 0 :(得分:2)
在Java中,受保护的成员可以访问子类和定义成员的包,另一方面,成员只对子类可见。
在您的情况下,代码可能是从实现A的类(例如来自工作表)
之外调用的如果要模拟Java行为,则可以使用符号
protected[package_name] def g(i: Int) = println(i)
然后,方法g()
将在包package_name
答案 1 :(得分:2)
我会继续让我的评论回答。 It's a bug。它确实应该按照你期望的方式工作,但事实并非如此。
答案 2 :(得分:1)
您不必仅使用override
来玩游戏进行测试。你可以这样做:
package com.foo.bar
trait MyTrait{
def stuff(i: Int) = hidden(i) + 1
protected[bar] hidden(i: Int): Int
}
然后在测试文件中
package com.foo.bar
class Testing extends Specification{
"hidden" must{
//some tests in here
}
这是另一种说法,“hidden
在包级别可见,因此该包中的任何内容都可以查看/测试它。”