I just ran into a difficulty while learning Scala. I have an inheritance hierarchy that is essentially equivalent to this:
class A {
protected def myMethod() = println("myMethod() from A")
}
class B extends A {
def invokeMyMethod(a: A) = a.myMethod()
}
But trying to compile this sample, I get the error "test.scala:7: error: method myMethod cannot be accessed in A".
Coming from Java, my understanding is that protected members should be accessible at any point from a derived class, and nowhere have I seen anything that tells me that protected members in Scala are limited by instance. Does anyone have an explanation for this?
Protected members in a class are similar to private members as they cannot be accessed from outside the class.
Unlike in Java, in Scala members that are protected are not accessible from other unrelated classes, traits or objects in the same package. There is no direct equivalent to Java's default access level in Scala.
Protected members that are also declared as static are accessible to any friend or member function of a derived class. Protected members that are not declared as static are accessible to friends and member functions in a derived class only through a pointer to, reference to, or object of the derived class.
Access Modifiers in scala are used to define the access field of members of packages, classes or objects in scala. For using an access modifier, you must include its keyword in the definition of members of package, class or object. These modifiers will restrict accesses to the members to specific regions of code.
Quoting the Scala Language Specification:
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.
These three rules define when exactly an instance is allowed to access another instance's protected members. One thing that's interesting to note is that, by the last rule, when B
extends A
, an instance of A
may access protected members of a different instance of B
... but an instance of B
may not access protected members of another A
! In other words:
class A {
protected val aMember = "a"
def accessBMember(b: B) = b.bMember // legal!
}
class B extends A {
protected val bMember = "b"
def accessAMember(a: A) = a.aMember // illegal!
}
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