2010-06-18 4 views
29

나는 relation 패키지의 database.relation 하위 클래스, Join 패키지의 database.operations이라는 추상 클래스를 가지고 있습니다. relation에는 mStructure이라는 보호 된 구성원이 있습니다.다른 패키지에있을 때 내 서브 클래스가 수퍼 클래스의 보호 된 변수에 액세스 할 수없는 이유는 무엇입니까?

Join에서 :

The field Relation.mStructure is not visible

:

public Join(final Relation relLeft, final Relation relRight) { 
     super(); 
     mRelLeft = relLeft; 
     mRelRight = relRight; 
     mStructure = new LinkedList<Header>(); 
     this.copyStructure(mRelLeft.mStructure); 

     for (final Header header :mRelRight.mStructure) { 
     if (!mStructure.contains(header)) { 
      mStructure.add(header); 
     } 
    } 
} 

라인

this.copyStructure(mRelLeft.mStructure); 

나는 다음과 같은 오류가

for (final Header header : mRelRight.mStructure) { 

두 클래스를 같은 패키지에 넣으면 완벽하게 작동합니다. 누구든지이 문제를 설명 할 수 있습니까?

답변

25

그것은 작동을하지만, 만 아이들은 그것을 변수하지 자신의 변수를 액세스하려고 다른 인스턴스의 (동일한 상속 트리에 속하더라도).

것은 더 잘 이해하기 위해이 샘플 코드를 참조하십시오

//in Parent.java 
package parentpackage; 
public class Parent { 
    protected String parentVariable = "whatever";// define protected variable 
} 

// in Children.java 
package childenpackage; 
import parentpackage.Parent; 

class Children extends Parent { 
    Children(Parent withParent){ 
     System.out.println(this.parentVariable);// works well. 
     //System.out.print(withParent.parentVariable);// doesn't work 
    } 
} 

우리는 우리가 가진 한 withParent.parentVariable를 사용하여 컴파일하려고하면 :

Children.java:8: parentVariable has protected access in parentpackage.Parent 
    System.out.print(withParent.parentVariable); 

그것은 오직 자신의 변수, 접근 .

+0

적절한 해결책은 보호 된 접근자를 정의하는 것입니까? –

+1

같은 일이 일어날 것입니다. 더 흥미로운 것은 'Join'이 IS-A '관계'인지, 그리고 그렇다면 왜 다른 패키지에 들어가야 하는지를 아는 것입니다. 아마도 중간 객체를 사용하여 구조를 추상화하고 할 것입니다. 코딩 마비를 피하기 위해 지금은 같은 패키지로 옮길 것을 제안합니다. – OscarRyz

+0

하위 클래스의 * 인스턴스 나 하위 클래스 *를 상속 한 인스턴스의 모든 인스턴스에서 해당 멤버에 액세스 할 수 있다고 자식 클래스에서 말할 경우 첫 문장을 좀 더 정확하다고 믿습니다. 자식 클래스가 상속하는 클래스의 모든 인스턴스 (사양의 6.6.2.1 절 참조 : http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2). 따라서 더 파생되지 않은 구성원 만이 아니라 상속 트리의 추가 파생 멤버에서이를 볼 수 있습니다. –

2

protected 경우, Join의 인스턴스는 패키지 외부의 다른 인스턴스 (relRight, relLeft)에 mStructure에 액세스 할 수 없습니다.

편집 :

here는 꽤 잘 이러한 상황을 설명합니다. 나는 []

Access Levels 
Modifier Class Package Subclass World 
public  Y  Y  Y   Y 
protected Y [Y]  Y   N 
no modifier Y  Y  N   N 
private  Y  N  N   N 
+0

첫 번째 설명에 한해서만 OP가 묻습니다. 첫 번째 위치에 * "액세스 할 수 없습니다"*. 귀하의 편집은 문제를 분명히하지 않습니다. – OscarRyz

+0

내 첫 번째 설명이 너와 거의 똑같다고 말한다. –

+0

그리고 편집과 관련하여 테이블이 문제를 어떻게 명확히하지 않습니까? OP는 테이블을 기반으로 기대할 수있는 행동을 묘사했습니다. 클래스의 인스턴스는 동일한 패키지에있는 모든 클래스의 다른 인스턴스의 보호 된 멤버에 액세스 할 수 있습니다. 또한 클래스의 인스턴스는 상위 클래스가 다른 패키지에 있더라도 상위 클래스에 정의 된 보호 된 멤버에 액세스 할 수 있습니다. –

13

조금 알려진주의에 대한 protected하여 문제의 원인 표시 :

6.6.2 Details on protected Access

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

+2

§6.6.7에있는 예제는 여기서 유용합니다. – Artefacto

+0

"구현 책임"을 명확히하는 공식 정의는 §6.6.2.1에 있습니다. – meriton

0

다른 인스턴스로 보호 된 멤버에 액세스하는 것이 문제입니다.

이 두 방법 부모 클래스에서 선언 할 수 있습니다 가능하면 예를 들어, 여러 솔루션을 적용 할 수 있습니다 차일에서 다음

protected void copyRelationStructure(Relation r) { 
    this.copyStructure(r.mStructure); 
} 

protected void mergeRelationStructure(Relation r) { 
    for (final Header header: r.mStructure) { 
    if (!mStructure.contains(header)) { 
     mStructure.add(header); 
    } 
    } 
} 

와 코드 교체 :

this.copyStructure(mRelLeft.mStructure); 

for (final Header header :mRelRight.mStructure) { 
    if (!mStructure.contains(header)) { 
    mStructure.add(header); 
    } 
} 

으로 :

this.copyRelationStructure(mRelLeft); 
this.mergeRelationStructure(mRelRight); 

그래야합니다.이제 관계는 자체 내부와 함께 작업을 자식에게 허용하는 메서드를 제공 할 책임이 있습니다. 아마도이 정책의 이유는 비 호환성을 제한하기 위해 동일한 소프트웨어 번들에 속하지 않는 한 어린이는 부모의 내부 구조를 혼동해서는 안됩니다.

관련 문제