scala覆盖受保护的成员函数

时间:2014-02-10 14:37:20

标签: scala

我想实例化一个特征并覆盖受保护的函数 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 {}

谢谢!

3 个答案:

答案 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在包级别可见,因此该包中的任何内容都可以查看/测试它。”