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!
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With