Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala override protected member function

Tags:

scala

I wanted to instantiate a trait and override a protected function g, making it accessible (function f is for testing).

trait A {
    protected def g( i: Int ) = println( i )
    def f( i: Int ) = println( i )
}

I created an object 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)
}

and tried to call the methods

a1.f(1)
a1.g(3)    // this call fails
a1.h(5)

For a1.g(3) I get this error:

<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

But when I define a trait A2 extending A and overriding the methods f and g, create an instance of it and call the methods, all works fine

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)

Why is there a difference between

val a1= new A {
    override def g( i: Int ) = super.g(i)
}

and

trait A2 extends A {
    override def g( i: Int ) = super.g(i)
}
val a2= new A2 {}

?

Thanks!

like image 854
user3293103 Avatar asked Feb 10 '14 14:02

user3293103


2 Answers

I'll just go ahead and make my comment an answer. It's a bug. It really should work the way you expect, but it doesn't.

like image 192
Ian McLaird Avatar answered Oct 04 '22 02:10

Ian McLaird


In Java protected member is accessible to both subclasses and the package in which the member is defined, in Scala, on the other hand, member is visible only to subclasses.

In your case, the code is probably called from outside of a class implementing A (e.g. from worksheet)

If you want to simulate Java behavior, then you can use notation

protected[package_name] def g(i: Int) = println(i)

then, the method g() will be visible inside the package package_name

like image 28
rarry Avatar answered Oct 04 '22 00:10

rarry