Protected Members of Other Instances in Scala

2019-04-06 00:05发布

问题:

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?

回答1:

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!
}