2011-01-07 13 views
9

Me encontré con una dificultad al aprender Scala. Tengo una jerarquía de herencia que es esencialmente equivalente a esto:Miembros protegidos de otras instancias en Scala

class A { 
    protected def myMethod() = println("myMethod() from A") 
} 

class B extends A { 
    def invokeMyMethod(a: A) = a.myMethod() 
} 

Pero tratar de compilar este ejemplo, me sale el error "test.scala: 7: Error: myMethod método no se puede acceder en A".

Viniendo de Java, entiendo que los miembros protegidos deben estar accesibles en cualquier punto de una clase derivada, y en ninguna parte he visto nada que me diga que los miembros protegidos en Scala están limitados por ejemplo. ¿Alguien tiene una explicación para esto?

Respuesta

17

Citando al 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.

Estas tres reglas definen cuándo exactamente se permite una instancia para acceder a los miembros protegidos de otra instancia. Una cosa que es interesante observar es que, según la última regla, cuando B se extiende a A, una instancia de A puede acceder a miembros protegidos de una instancia diferente de B ... ¡pero una instancia de B no puede acceder a miembros protegidos de otra A! En otras palabras:

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

Esta explicación no dice por qué el código del OP no funciona. 'B' _es_ un tipo derivado de' A', justo como se supone que es. –

+2

'B' se deriva de' A', pero está intentando acceder no a su propio miembro protegido 'myMethod', sino a la de otra instancia, el parámetro' a: A'. Un miembro protegido solo es visible para la _instance que lo contiene_ (de forma predeterminada, aunque esto se puede modificar con la anotación de scoping que mencioné). –

+1

Eso contradice bastante el pasaje que ha citado: "incluidas otras instancias del mismo tipo y cualquier tipo derivado". – Submonoid

Cuestiones relacionadas