flamecto
flamecto

Reputation: 139

Accessing a protected value of a superclass argument in a subclass of the superclass

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

Answers (2)

Alexey Romanov
Alexey Romanov

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

chengpohi
chengpohi

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

Related Questions