2011-01-07 2 views
9

스칼라를 배우는 동안 어려움에 처했습니다. 나는이 본질적으로 동일하다 상속 계층 구조를 가지고 :스칼라에있는 다른 인스턴스의 보호 된 멤버

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

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

그러나이 샘플, 나는 오류를 컴파일하려고 "test.scala : 7 : 오류 : 메서드 MyMethod라는이에 액세스 할 수 없습니다."

Java에서 제공되는 것은 보호 된 멤버가 파생 클래스의 어느 지점에서나 액세스 할 수 있어야한다는 것입니다. 스칼라의 보호 된 멤버가 인스턴스에 의해 제한된다는 것을 알 수있는 내용은 어디에도 없습니다. 누구든지 이것에 대한 설명이 있습니까?

답변

17

에 따옴표 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.

이 세 가지 규칙이 인스턴스가 다른 인스턴스의 보호 된 멤버에 액세스 할 수 때 정확히 정의합니다. 흥미로운 점은 마지막 규칙에 따라 BA으로 확장되면 A의 인스턴스가 B의 다른 인스턴스의 보호 된 멤버에 액세스 할 수 있지만 B의 인스턴스가 다른 A의 보호 된 멤버에 액세스 할 수 없다는 것입니다. 즉 :

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

이 설명은 실제로 OP 코드가 작동하지 않는 이유를 설명하지 않습니다. 'B' _는 파생 된 타입의 'A'입니다. –

+2

'B'는'A'에서 파생되었지만 자체 보호 된 멤버 인 myMethod가 아니라 다른 인스턴스의 매개 변수 인'a : A'에 액세스하려고 시도하고 있습니다. 보호 된 멤버는 it_이 포함 된 _instance에서만 볼 수 있습니다 (기본적으로 언급 한 범위 지정 주석으로 수정할 수 있음). –

+1

오히려 당신은 인용 한 글을 "이와 동일한 유형과 파생 된 유형의 다른 인스턴스를 포함하여"와 오히려 모순됩니다. – Submonoid