2009-05-24 4 views
39

Java에서 "protected"한정자를 가진 멤버는 동일한 클래스와 하위 클래스뿐만 아니라 동일한 패키지의 모든 구성원이 액세스 할 수있는 이유는 무엇입니까?Java의 "protected"한정자가 같은 패키지의 다른 클래스에 대한 액세스를 허용하는 이유는 무엇입니까?

나는 언어 설계 이유로, 실제적인 응용 프로그램

+10

+1 솔직하게 나는 왜뿐만 아니라 알고 싶습니다. 그것은 항상 Java에서 가장 멍청한 디자인 결정 중 하나로 나를 때렸습니다. – cletus

+1

@cletus : 너무 오랫동안 생각해 보니 "패키지 개인"은 잘 생각하지 못한 아이디어였습니다. "package private"을 실제 작업에 적용하고 모든 종류의 실제 보호를 제공하려면 패키지를 단일 컴파일 단위 내에서 컴파일해야합니다. 그리고 나중에 그것을 향상시킬 수는 없습니다. – Martin

답변

22

이 디자인은 패키지가 유지 하나 개 내부적으로 일관성이 팀에 의해 발표 적절한 장치,이라는 생각에 기초한다 (예를 들어, 테스트)에 대해 궁금; 상속 관계는 누가 언제 무엇을 유지하고 발표하는지와 관계가 거의 없습니다.

+1

답변 해 주셔서 감사합니다. 아무리 많은 항아리에 패키지를 배포하는 것을 중단 한 사람이 없기 때문에 물론 실제로는 작동하지 않습니다. 그래서 완전히 생각하지 않은 다른 좋은 아이디어입니다. 뭔가 자바가 가득합니다. – Martin

7

기본적으로 패키지를 api 제어 단위로 볼 수 있으므로 도메인 이름으로 패키지를 시작하는 것이 좋습니다 (전역 고유성 보장). 따라서 공개 설정은 개인 -> 패키지 - 개인> 보호 된 -> 공개. 보호받는 패키지가 개별 패키지가 아닌 다른 유형의 가시성보다 증가하지 않으면 필요할 때 두 가지 유형의 가시성을 결합 할 수있는 방법이 필요합니다.

+0

그러나 이미 종료 된 패키지에 새 클래스를 추가하는 것을 중지시키는 사람은 아무도 없습니다. 따라서 "개인 패키지"와 "보호"는 프로그래머에게만 권장 할만한 것입니다. 이 두 가지 방법 모두이 방법을 원하거나 필요로하는 악의적 인/필사적 인 프로그래머로부터 어떠한 실질적인 보호도 제공하지 않습니다. - C++에서와 같이 "protected"는 적어도 하위 클래스의 사용을 강요하지만 Java에서는 그렇게 할 필요조차 없습니다. – Martin

1

액세스 레벨이 개인, 패키지, 보호 및 공용 인 경우, 동일한 패키지의 다른 구성원에게 권한을 부여하기 위해 하위 클래스에 대한 액세스를 허용해야하기 때문에 패키지가 보호 된 후 불필요하게 제한 될 수 있습니다. 그러나 직관적으로, 같은 패키지에있는 다른 클래스가 "out"다른 클래스보다 더 신뢰할 수 있어야합니다. 그래서 패키지와 대중 사이의 접근은 더 넓은 노출을 허용한다는 점에서 보호됩니다.

기본적인 이유는 동일한 패키지의 클래스간에 기본적인 수준의 "신뢰"가 있다는 직관에 의존한다고 생각합니다. 대부분의 경우 패키지가 단일 엔지니어 또는 팀의 책임이되므로 일관된 디자인 조화가 있어야합니다.

+0

그것은 이론입니다. 그러나 실습에서는 패키지가 단일 컴파일 단위로 컴파일되어야하고 외부에서 향상 될 수없는 경우에만 사실입니다. 그러나 그렇게되지는 않으므로 슬림 한 대표 클래스를 사용하여 "패키지 개인"메서드를 공개 할 수 있습니다. 프로그래머에게는 힌트이지만 진정한 보호는 아닙니다. – Martin

+0

@martin : 봉인하지 않고 패키지를 게시 한 경우에만이 특정 문제를 해결할 수 있습니다. –

+0

"패키지 봉인"- 들어 본 적이 없지만 재미있을 것 같습니다. ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 더 많은 정보를 말해 줄 수있는 몇 가지 단어 – Martin

20

수정자는 잘 설명 된 at http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html입니다. 거기에서 우리는이 그림을 봅니다. 디자인 결정이 이유에서

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 

는 분명하다 : 그것은 좋은 대칭 행렬을 가지고 있습니다.

+4

어쨌든 대칭이 될 것입니다 ... –

+0

이 테이블을 가져 주셔서 감사합니다. – Marin

+0

@Michael Myers : 음, 아니요, 어쨌든 대칭 적이 지 않습니다. 이유 때문에 대칭입니다. – Glenn

13

Java 1.0에는 다섯 번째 액세스 수정자가 있습니다 (private protected). 기본 액세스 권한이없는 protected입니다. 분명히 실제로 제대로 작동하지 않았으며 1.1에서 삭제되었습니다. 따라서 총 주문에 대한 방식이 거짓 인 것으로 보이는 방식으로 protected이 정의 된 것처럼 보입니다. Java 7의 module 액세스 수정자는이 영역에서 몇 가지 디자인 관련 질문을합니다.

구성원의 기본 액세스 수정자가 "패키지 개인"으로되어있는 것이 좋을 것으로 생각되면 protected이 최소한이 수준의 액세스 권한을 가져야합니다. 내 돈을 위해서 protected은 언어로 지불하지 않습니다.

+0

나는 그 중 하나에 대해 들어 본 적이 없지만, 나는 1.1로 Java에 들어갔다 ... 고마워! – Uri

+0

그리고 아무도 다른 jar 파일의 패키지에 클래스를 추가하는 것을 중지시키지 않으므로 "package private"가 모두 private가 아닙니다. 그것이 그렇듯 : 사적인 것과 공공을 제외하고는 프로그래머에게는 다소 힌트가 있지만 실질적인 보호는 없다. – Martin

0

Java는 자체 디자인 원칙을 따릅니다. 하위 클래스의 공용 메소드의 범위를 축소/축소하려고하면 어떻게됩니까? 오류가 발생합니다. 자바 범위 수정 레벨은 다음과 같습니다 개인 < (기본값) < 패키지의 모든 클래스가 함께 작동하기 때문에 친절로되어있다

공공 <을 보호. 구성원을 패키지로 사용 가능하게 만들려면 기본 범위에 정의되어 있어야합니다.

범위 수준에 따라 서브 클래스가 패키지 외부에있을 수 있습니다. private < (기본값) < protected < public - 범위를 좁힐 수 없습니다. 보호가 기본값보다 넓은 범위이므로 Java는 자체 지침과 모순되지 않습니다. 따라서 보호 된 구성원은 기본 범위에서 사용할 수 있습니다. 또한 : 클래스 < 패키지 < 프로젝트.

수정 기호는 가시성 만 제한하지 말고 상속, 구조는 동시에 작업하고 그림에도 추가하십시오. 이 경우 : < 개인 < (기본값) < 공개. 모든 하위 클래스가 동일한 패키지에 있어야하며, 패키지 레벨에서 적용 할 수있는 기본 범위가 있으므로 모든 하위 클래스를 상속해야합니다. 기본 범위는 가치를 상실하고 상속을 상실합니다.