2013-03-15 6 views
2

파생 클래스에 전혀 노출되지 않도록하거나 적어도 서브 클래스가 super()을 호출 할 때까지 클래스 멤버를 선언 할 수 있는지 궁금합니다. Java에 이러한 기능이 있습니까?거기에 슈퍼 클래스의 멤버를 파생 클래스에서 숨길 수있는 방법이 있습니까?

class A{ 
     static int foo = 1; 
    } 

    class B extends A{ 
     public B(){ 
     System.out.print(foo);/// how do I make this not work? 
     } 
    } 

편집 : 실수로 솔루션에 대한 내 질문을 입력했습니다 (실제 코드에 개인 코드가 누락되었습니다). 회원이 비공개 그렇다면,

그러나 B.에서 표시되지 않습니다, - 그것은 의미있는 질문 :

+2

'foo'는 'A'에 'private'로 표시했기 때문에 이미'B'에 보이지 않습니다. – rgettman

+0

'super.somethingHere'를 사용할 때까지는 사적인 것으로 보이는 것을 원한 것처럼 보입니다. 맞습니까? 음, 이것은 불가능합니다. 유일한 해결책은'protected'를 사용하는 것이므로 자식 클래스 만 부모 클래스 필드/메소드에 액세스 할 수 있습니다. –

+0

@LuiggiMendoza 한 상황에서 가능합니다 : A와 B가 동일한 최상위 클래스를 공유하는 경우. B는'super.foo'에 접근 할 수 있지만'foo'는 접근 할 수 없습니다 – ZhongYu

답변

3

이미 작동하지 않습니다이다 있도록 그래서 난 내 질문을 편집하고 개인을 제거 할 수 있습니다 당신은 하위 클래스에서 이미 가시적 인 멤버를 숨기려고합니다.

public class A { 
    public void foo() { 
     // Whatever 
    } 
} 

public class B extends A { 
    // ??? 
} 

... 
B b = new B(); 
b.foo(); // I don't want this to work, because it's a B! 

... 그럴 수 없습니다. Liskov's Substitution Principle이 나옵니다.

+0

정말 재밌 네요, 존. 코드에 개인 코드가 누락되어 코드가 실수로 생성되어 솔루션을 내장 할 수있게되었습니다. :) 감사. –

+0

B에서'foo'를 항상 오버라이드하여 (실제로 원한다면) 에러를 던질 수 있습니다. – sdasdadas

+1

@sdasdadas : 예, 그렇습니다. 그러나 이것은 실제로 동일한 것은 아니며 런타임 예외 (또는 기본 클래스에서 이미 선언 된 일부 예외) 여야합니다. –

1

변수를 private으로 표시하면 하위 클래스는 변수에 액세스 할 수 없게됩니다.

(또한, 당신은 아마 당신의 foo는 선언 static을하지 않습니다.) 질문

+0

실제로 나는 할 수 있습니다 ... 그러나 나는 더 이상 문맥이 없으면 특이하게 보일 수도 있습니다. –

2

하나 개의 해석은 당신이 실패 할 foo에 접근하지만, 성공 super.foo에 접근하려는 것입니다. A와 B가 모두 같은 최상위 클래스에 포함되어 있거나 그 중 하나가 다른 클래스를 감싸는 최상위 클래스 인 경우 특정 상황에서 발생할 수 있습니다.

class X 

    class A 
     private int foo; 

    class B extends A 

     print(foo);   // fail 
     print(super.foo);  // ok 
     print(((A)this).foo); // ok... 

또는

class A 
    private int foo; 

    static class B extends A // declared inside A 

     print(foo);   // fail 
     print(super.foo);  // ok 
     print(((A)this).foo); // ok... 

이유는 그 개인 회원 그래서 this.foo이 존재하지 않는, 상속되지이다; 적절한 수식어를 사용하여 최상위 클래스에서 액세스 할 수 있으므로 A.foo에 액세스 할 수 있습니다. http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.1-100-D-3

+0

내 상황에서 B는 A 안에 선언되어 있지 않지만, 정말 잘 알고 있습니다!, 감사합니다. –

+0

두 번째 코드 블록은 말했을 때 실패하지 않습니다. 이것은 비 정적 내부 클래스가 최상위 클래스의 속성에 액세스 할 수 있기 때문입니다.이 정보를 추가하지 않으면 오해의 소지가있는 OP입니다. –

+0

@LuiggiMendoza 예 정적이어야합니다. 나는 코드를 테스트하지는 않았지만, 일반적인 생각은'private '멤버가 상속되지 않는다는 것이다.하지만 최상위 클래스에서 액세스 할 수있다. – ZhongYu

1

액세스 수정 자 (예 : private이라는 멤버를 선언하는 것)는 실제로 회원에 대한 액세스를 차단하는 유일한 것입니다. (그리고 그렇다하더라도, 당신은 어쨌든 private 멤버를 잡아 반사를 사용할 수 있습니다.) 당신이 super을 언급 할 때, 당신은 자바 의미에서을 숨기고 를 사용하여 생각 될 수


; 예 : 여기서 원래 선언을 숨기려면 foo이라는 다른 것을 선언하십시오. 그러나 여기서는 도움이되지 않습니다.

  • 당신은 B에서 2 foo 또는 A 이상 등의 일부 서브 클래스 C를 선언해야 할 것이다는 ... C를 확장 B를 확장합니다.

  • B은 항상 foo으로 A.foo으로 액세스 할 수 있습니다. 실제로, <class>.<name>이 권장 접근법이기 때문에,이 (가상의) 은신처 사용은 가치있는 것을 얻지 못했습니다 (IMO).

  • 작동하는 정도까지도 foo은 단순히 foo으로 바뀌며 이는 사용 사례에 필요하지 않습니다. 짧은 숨어에서

는 감소 또는 노출을 제어하는 ​​효과적인 수단이 아니다.

관련 문제