Reputation: 139
In the following Scala code, B
extends A
, and also takes A
as an argument in its constructor. B
can access foo
from the superclass, but not from the superclass object passed in.
class A() {
protected val foo = 1
}
class B(a: A) extends A {
println(foo) // okay
println(a.foo) // fail - "access to protected value foo not permitted"
}
Is there a way to successfully get a.foo
in B
without using reflection and without changing the modifier to protected[package]
?
Upvotes: 0
Views: 53
Reputation: 170745
The specification (linked in chengpohi's answer) says:
A protected identifier x may be used as a member name in a selection r.x only if one of the following applies:
- The access is within the template defining the member, or, if a qualification C is given, inside the package C, or the class C, or its companion module, or
- r is one of the reserved words this and super, or
- r's type conforms to a type-instance of the class which contains the access.
The first says that foo
can be accessed in A
itself (the second part doesn't apply because you don't use protected[C]
) and so doesn't help you.
The second doesn't apply.
The third says that the receiver's type (which is A
in this case) must conform to B
, which it doesn't.
So none of the three conditions apply, the access is illegal, and you must change one of the above factors to make it legal.
Upvotes: 1
Reputation: 14217
You can use package protected to declare variable, so it can be used under the current package, example:
package foobar {
class A {
//package protected variable
protected[foobar] val foo = 1
}
class B(a: A) extends A {
println(foo) // okay
println(a.foo) // fail - "access to protected value foo not permitted"
}
}
import foobar._
val b = new B(new A)
Upvotes: 1