我想实例化一个特征并覆盖受保护的函数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 {}
?
谢谢!
我会继续让我的评论成为答案。 这是一个错误。 它确实应该按照您期望的方式工作,但事实并非如此。
在 Java 中,受保护的成员可以被子类和定义成员的包访问,另一方面,在 Scala 中,成员仅对子类可见。
在您的情况下,代码可能是从实现 A 的类外部调用的(例如,从工作表)
如果要模拟 Java 行为,则可以使用表示法
protected[package_name] def g(i: Int) = println(i)
然后,方法g()
将在包package_name
内可见
您不必为了测试而与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
在包级别是可见的,因此该包中的任何内容都可以看到/测试它。