2014-09-13 2 views
2

나는 protected 수식어가 이해한다고 생각했지만 그렇지 않은 것 같습니다. 예는 간단하다 :다른 패키지에서 보호 된 메서드 호출

package com; 
public class Main { 

    protected void method1() { 
     // some code 
    } 
} 

과 :

package net; 

import com.Main; 

public class Out extends Main { 

    public Out(){ 
     Main m = new Main(); 
     m.method1(); 
    } 
} 

가 왜 Main를 확장하는 클래스에서 method1를 호출 할 수 없습니다? 컴파일러 오류로 인해 수정자를 public으로 변경하는 것이 좋습니다.

나는 정말로 혼란 스럽다.

답변

0

당신이 (AN OutMain이지만, MainOut되지 않습니다) Out에서 Main 인스턴스를 생성하기 때문에이 작동하지 않습니다.

직접 method1 전화 할게 경우가 작동합니다

public Out(){ 
    method1(); 
} 

또는 당신이 Out 인스턴스가있는 경우 :

public Out(){ 
    Main m = new Main(); 
    ((Out)m).method1(); 
} 

또는

public Out(){ 
    Out m = new Out(); 
    m.method1(); 
} 

Here 일부를 찾을 수 있습니다 세부 정보 (6.6.2 절) :

개체의 보호 된 멤버 또는 생성자는 해당 개체의 구현을 담당하는 코드에 의해서만 선언 된 패키지 외부에서 액세스 할 수 있습니다.

+0

첫 번째 코드 예제는 메서드가 아닙니다. 자바에서는'constructor'이라고합니다. 그리고 그것은 매우 분명합니다. 그는 단지 생성자를 내 생성자 중 하나로 대체 할 수 있으며 모든 것이 잘 작동합니다. –

+0

'Out' 클래스의'method1()'이 생성자가 아닙니다. – ataulm

+0

'public Out()'= public 생성자입니다. 'method1()'= 메소드 호출; 나는 모든 것이 분명하다고 생각한다. Main으로부터 상속받은 보호 된 메소드이기 때문에 그는'method1'를 직접 호출 할 수 있습니다. –

0
package com.example.furniture; 

public class Seat { 

    public boolean canAccommodate(int numberOfPeople) { 
     return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate(); 
    } 

    protected int getMaxNumberOfPeopleThatICanAccommodate() { 
     return 4; 
    } 

} 


package com.example.furniture; 

public class Chair extends Seat { 

    public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) { 
     return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate(); 
    } 

} 

위의 내용 getMaxNumberOfPeopleThatICanAccommodate()Chair에 명시 적으로 정의되지 않은 경우에도 작동합니다, ChairSeat에서 구현을 사용합니다. protected 개질제 서브 메소드 호출 (또는 무시) 할 수 있고, 또한 방법 전화 같은 패키지의 클래스를 허용 :

package com.example.furniture; 

public class Bed { 

    public boolean canFitMorePeopleThanThis(Seat seat) { 
     return peopleICanFit() > seat.getMaxNumberOfPeopleThatICanAccommodate(); 
    } 

    private int peopleICanFit() { 
     return 2; 
    } 

} 

및 보호 방법과 함께 하나의 확장 클래스가 너무 메소드를 재정의 할 수

package com.example.furniture; 

public class ReallySmallChair extends Seat { 

    public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) { 
     return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate(); 
    } 

    @Override 
    protected int getMaxNumberOfPeopleThatICanAccommodate() { 
     return 1; 
    } 

} 

그러나 외부 패키지에서 보호 방법에 액세스하려고하면, 그것은 작동하지 않습니다

package com.example.room; 

public class LivingRoom { 

    Seat seat = new Seat(); 
    Seat chair = new Chair(); 

    public boolean canAccommodate(int numberOfPeople) { 
     int maxAccommodate = seat.getMaxNumberOfPeopleThatICanAccommodate() + 
       chair.getMaxNumberOfPeopleThatICanAccommodate(); 

     return numberOfPeople <= maxAccommodate; 
    } 

} 

당신은 컴파일러를 얻을 수 있습니다 seat.get... 또는 chair.get... 방법에 액세스하려고 할 때 오류가 발생했습니다.

다른 패키지에 Seat 하위 클래스가있는 경우 두 조건 중 하나 (동일한 패키지의 하위 클래스 또는 다른 클래스) 중 하나를 충족시키기 때문에 보호 된 메서드에 액세스 할 수 있지만 자체 메서드 만 사용할 수 있습니다 :

getMaxNumberOfPeopleThatICanAccommodate() RecreationalVehicle에 (이 서브 클래스의)에 속하는하는 방법이기 때문에, 작동
package com.example.room; 

public class RecreationalVehicle extends Seat { 

    public boolean canAccommodate(int numberOfPeople) { 
     return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate();    
    } 

} 

. 그것은 Seat 변수에서 액세스하려고하면 RecreationalVehicle은 (는) 동일한 패키지에없는 같은 다른 인스턴스의 보호 방법을 만져 허용되지 않기 때문에, 그것을 허용하지 않을 :

package com.example.room; 

public class RecreationalVehicle extends Seat { 

    Seat seat = new Seat(); 

    public void foo() { 
     seat.getMaxNumberOfPeopleThatICanAccommodate();    
    } 

} 

는 컴파일러 오류가 발생합니다. 당신이 실제로 다른 패키지에서 슈퍼 클래스의 메소드를 호출 할 수처럼

0

그것은 보이는, 그냥 질수 명시 적으로 수행

package com.example.room; 

import com.example.furniture.Seat; 

public class RecreationalVehicle extends Seat{ 

RecreationalVehicle rec = new RecreationalVehicle(); 

public boolean canAccomodate(int numberOfPeople){ 

    int n = rec.getMaxNumber(); 

    getMaxNumber(); 
    return true; 
    } 
} 

이 클래스는 getMaxNumber(), 아직 통화 rec.getMaxNumber을 (구현 해달라고)한다 승인. 그것은 슈퍼 클래스에 대한 실제 호출입니다.

요점은 : '부모'참조 유형이있는 객체에서 다른 패키지의 수퍼 클래스 메소드를 호출 할 수없는 이유는 무엇입니까?

+0

귀하의 질문에 대한 답변이 아니기 때문에이 답변을 게시해서는 안됩니다. @ curiosu의 대답 끝에 게시 된 인용문은 - 패키지의 외부에서 [보호 된 메소드]에 액세스 할 수있는 _only_ 시간은 ** 해당 객체의 구현을 담당하는 코드에 의해 선언 된 경우입니다 **. 서브 클래스는 구현을 담당하므로 서브 클래스가 다른 패키지에 있더라도 슈퍼 클래스의 메소드를 호출 할 수 있습니다. – ataulm

+0

위에서 얻은이 코드 샘플에서는 RV 클래스에 있기 때문에 RecreationalVehicle _field_의 _private_ 멤버에 액세스 할 수 있습니다. private 한정자는 클래스 내에서 액세스를 허용합니다. Seat 클래스는이 범위 밖에 있습니다. RV는 Seat 클래스를 변경하거나 수정할 수 없습니다. 미묘한 차이점이 있습니다. / – ataulm

관련 문제