Java에서 대중, 보호, 패키지 및 개인 및 비공개의 차이점은 무엇입니까?


질문

 

Java에서는 각 액세스 수정자를 사용하는 경우, 클래스 및 인터페이스를 만들고 상속을 처리하는 동안 기본 (패키지 개인), 대중, 보호 및 비공개의 각 액세스 수정자를 사용하는시기에 대한 규칙이 분명합니다.


답변

 

공식 자습서는 귀하에게 사용될 수 있습니다.


Class Package Subclass
(same pkg)
Subclass
(diff pkg)
World
public + + + + +
protected + + + +
no modifier + + +
private +

+ : 액세스 가능 공백 : 액세스 할 수 없습니다



답변

(Caveat : 저는 Java 프로그래머가 아닙니다. 저는 Perl 프로그래머입니다. Perl은 아마도 내가 문제를 잘 이해하는 이유 일 것 인 공식적인 보호가 없습니다. :)))

사적인

당신이 생각하는 것처럼, 그것이 선언 된 수업 만 볼 수 있습니다.

패키지 개인

그것이 선언 된 패키지에서만 볼 수 있고 사용할 수 있습니다.이것은 Java의 기본값입니다 (일부는 실수로 볼 수 있음).

보호 된

패키지 개인 +는 하위 클래스 또는 패키지 구성원이 볼 수 있습니다.

공공의

모두가 그것을 볼 수 있습니다.

게시

코드 I 통제 밖에서 표시됩니다.(Java 구문이 아님)이 토론에 중요합니다).

C ++은 "친구"라는 추가 수준을 정의하고 더 잘 알고있는 것에 대해 알지 못합니다.

언제 무엇을 사용해야합니까?전체 아이디어는 정보를 숨기는 캡슐화입니다.가능한 한 많이 사용자로부터 무언가가 수행되는 방법에 대한 세부 사항을 숨길 수 있습니다.왜요?그런 다음 나중에 변경할 수 있으므로 아무도 코드를 깰 수 없습니다.이렇게하면 누군가가 방금 정비 한 코드를 사용하고 있음을 걱정하지 않고도 버그를 최적화, 리팩토러, 재 설계 및 수정할 수 있습니다.

따라서 엄지 손가락의 규칙은 그들이해야 할 때만 볼 수있는 것만으로 만드는 것입니다.비공개로 시작하고 필요에 따라 가시성을 더 많이 추가하십시오.사용자가 알아야 할 필요가있는 대중에게만 공개적으로 시스템을 재 설계 할 수있는 능력을 알려드립니다.

사용자가 내부를 대중으로 만들 수 있도록 사용자를 사용자 정의 할 수있게되기를 바라는 경우 종종 이러한 용기를 객체에 밀어 넣고 해당 인터페이스를 공개하는 더 좋은 아이디어입니다.그렇게하면 새 개체를 연결할 수 있습니다.예를 들어, CD 플레이어를 작성하고 "이 CD에 대한 정보를 찾으십시오"비트 사용자 정의를 원하는 경우 해당 메소드를 해당 모든 기능을 객체에 넣고 객체 getter / setter 공개 만 만들기를 원한다면.이런 식으로 당신의 배짱을 노출시키는 것에 대한 찌르는 것은 좋은 조성과 분리를 장려합니다.

나는 "비공개"와 "대중"을 고수합니다.많은 oo 언어 만 가지고 있습니다."보호 된"은 편리 할 수 있지만 속임수입니다.인터페이스가 비공개 이상이면 제어가 밖에 있고 다른 사람들의 코드를 찾아서 사용하기 위해 사용해야합니다.

이것은 "게시 된"의 아이디어가 들어오는 곳입니다. 인터페이스 (리팩토링)를 변경하려면 인터페이스를 변경하고 사용하는 모든 코드를 찾아 변경해야합니다.인터페이스가 비공개 인 경우 문제가 없습니다.보호되어있는 경우 모든 하위 클래스를 찾아야합니다.대중이면 코드를 사용하는 모든 코드를 찾아야합니다.예를 들어, 인터페이스가 공개되는 경우에만 내부 사용을위한 것에 대해서만 내부 사용을 위해 작업하는 경우에만 이는 가능합니다.모든 코드를 회사 저장소에서 가져올 수 있습니다.그러나 인터페이스가 "게시"된 경우 컨트롤을 벗어나는 코드가있는 경우 해드니다.인터페이스 또는 위험 강화 코드를 지원해야합니다.보호 된 인터페이스조차도 게시 된 것으로 간주 될 수 있습니다 (이는 내가 보호받지 않는 이유).

많은 언어는 공공 / 보호 / 비공개의 계층 적 특성을 너무 제한하고 현실과 일치하지 않습니다.이를 위해 특성 클래스의 개념이 있지만 다른 쇼입니다.



답변

여기에는 테이블의 더 나은 버전이 있습니다. 또한 모듈의 열이 포함되어 있습니다.

java

설명

개인 회원 (I)은 선언 된 것과 동일한 클래스에서만 액세스 할 수 있습니다. 액세스 수정 자 (j)가없는 구성원은 동일한 패키지의 클래스에서만 액세스 할 수 있습니다. 보호 된 회원 (K)은 동일한 패키지의 모든 클래스 및 다른 패키지의 서브 클래스 내에서 액세스 할 수 있습니다. 공개 멤버 (L)는 모든 클래스에 액세스 할 수 있습니다 (패키지가 선언 된 패키지를 내 보내지 않는 모듈에 상주하지 않는 한).


어떤 수정자를 선택할 수 있습니까?

액세스 수정자는 실수로 캡슐화 (*)를 방지하는 데 도움이되는 도구입니다.회원이 클래스, 패키지, 클래스 계층 구조 또는 내부에서 내부적이지 않은 무언가가되어 있거나 그에 따라 액세스 수준을 선택해야합니다.

예 :

필드 긴 internalcounter는 변경할 수 있고 구현 세부 사항이므로 비공개 일 것입니다. 팩토리 클래스 (동일한 패키지에서)에서만 인스턴스화되어야하는 클래스는 패키지가 제한된 생성자를 가져야합니다. 패키지 외부에서 직접 호출 할 수 없으므로. 렌더링되기 전에 오른쪽으로 불리는 내부 VOID BEFORERENDER () 메소드는 하위 클래스의 후크로 사용되어야합니다. GUI 코드에서 호출되는 void savegame 메소드는 공개되어야합니다.

(*) 캡슐화는 정확히 무엇입니까?



답변

____________________________________________________________________
                | highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
 \ xCanBeSeenBy | this          | any class | this subclass | any
  \__________   | class         | in same   | in another    | class
             \  | nonsubbed     | package   | package       |    
Modifier of x \ |               |           |               |       
————————————————*———————————————+———————————+———————————————+———————
public          |       ✔       |     ✔     |       ✔       |   ✔  
————————————————+———————————————+———————————+———————————————+———————
protected       |       ✔       |     ✔     |       ✔       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
package-private |               |           |               |
(no modifier)   |       ✔       |     ✔     |       ✘       |   ✘   
————————————————+———————————————+———————————+———————————————+———————
private         |       ✔       |     ✘     |       ✘       |   ✘    
____________________________________________________________________


답변

쉬운 규칙.모든 것을 비공개 선언하는 것으로 시작하십시오.그리고 나서 필요가 발생하고 디자인이 필요할 때 대중을 향해 진행하십시오.

회원들을 노출 할 때 표현 선택이나 추상화 선택을 드러내는 경우 직접 요청하십시오.첫 번째는 관찰 가능한 행동보다는 실제 표현에 너무 많은 종속성을 소개 할 때 피해야 할 것입니다.

일반적으로 서브 클래 싱에 의한 방법 구현을 무시하는 것을 피하려고 노력합니다.논리를 망치기에는 너무 쉽습니다.추상 보호 방법을 재정의 할 의도가 지정됩니다.

또한 리팩토링 할 때 사물을 깨뜨리지 않도록 탐색 할 때 @ 오버 리드 주석을 사용하십시오.



답변

실제로 간단한 그리드 쇼보다 조금 더 복잡합니다.그리드는 액세스가 허용되는지 여부를 알려줍니다. 그러나 정확히 액세스를 구성하는 것은 무엇입니까?또한 액세스 수준은 복잡한 방식으로 중첩 된 클래스와 상속과 상호 작용합니다.

"기본값"액세스 (키워드가없는 경우에 지정)는 패키지 - 비공개라고도합니다.예외 : 인터페이스에서는 수정자가 공개 액세스를 의미하지 않습니다.대중 이외의 수정자는 금지되어 있습니다.enum 상수는 항상 공개됩니다.

요약

이 액세스 지정자가 허용 된 구성원에 대한 액세스 권한이 있습니까?

멤버는 비공개입니다. 멤버가 호출 코드와 동일한 클래스 내에서 정의 된 경우에만. 멤버는 패키지 비공개입니다. 호출 코드가 회원의 즉시 묶는 패키지 내에있는 경우에만됩니다. 멤버는 보호 코드가 포함 된 클래스의 수퍼 클래스에 동일한 패키지 또는 멤버가 정의 된 경우. 회원은 공개됩니다 : 예.

어떤 액세스 지정자가 적용됩니다

로컬 변수 및 공식 매개 변수는 액세스 지정자를 사용할 수 없습니다.범위 규칙에 따라 외부에 본질적으로 접근 할 수 없기 때문에 효과적으로 비공개입니다.

최상위 범위의 수업의 경우 공개 및 패키지 만 사용할 수 있습니다.이 디자인 선택은 보호되고 비공개가 패키지 수준에서 중복 될 것이기 때문에 아마도 아마도 (패키지 상상이 없습니다).

모든 액세스 지정자는 클래스 멤버 (생성자, 방법 및 정적 멤버 함수, 중첩 클래스)에서 가능합니다.

관련 : Java 클래스 접근성

주문하다

액세스 지정자는 엄격하게 주문할 수 있습니다

공개> 보호> 패키지 - 개인> 비공개

그 의미는 대중이 가장 많이 액세스 할 수있는 것을 제공합니다.개인 멤버에서 가능한 모든 참조는 패키지 개인 구성원에도 유효합니다.패키지 개인 구성원에 대한 모든 참조는 보호 된 구성원에서 유효합니다.(보호 된 회원들에게 동일한 패키지의 다른 수업에 액세스 할 수 있으므로 실수로 간주됩니다.)

메모

클래스의 메소드는 동일한 클래스의 다른 객체의 개인 구성원에 액세스 할 수 있습니다.보다 정확하게 C 클래스 C의 메소드는 C. Java의 서브 클래스의 객체에 C의 개인 구성원에 액세스 할 수 있습니다. 인스턴스별로 액세스 제한을 지원하지 않습니다.(사설 [이]을 사용하여 지원하는 스칼라와 비교하십시오.) 객체를 구성하기 위해 생성자에 액세스해야합니다.따라서 모든 생성자가 사적이면 클래스는 클래스 내의 코드 (일반적으로 정적 팩토리 메소드 또는 정적 변수 이니셜 라이저)로만 구축 될 수 있습니다.패키지 개인 또는 보호 된 생성자와 유사하게 민간 생성자 만 있으면 Java가 SuperClass 생성자를 암시 적으로 또는 명시 적으로 호출하기 위해 하위 클래스의 생성자가 필요하기 때문에 클래스가 외부에서 서브 클래스를 유지할 수 없기 때문입니다.(그러나 그것은 서브 클래스를 서브 클래스하는 중첩 클래스를 포함 할 수 있습니다.

내부 수업

또한 내부 클래스와 같은 중첩 범위를 고려해야합니다.복잡성의 예는 내부 수업이 액세스 수정자를 취할 수있는 구성원을 가지고 있다는 것입니다.따라서 공개 회원이있는 개인적인 내부 수업을 가질 수 있습니다.회원에 액세스 할 수 있습니까?(아래 참조) 일반 규칙은 범위를보고 각 레벨에 액세스 할 수 있는지 여부를 확인하기 위해 재귀 적으로 생각하는 것입니다.

그러나 이것은 매우 복잡하며 자세한 내용은 Java 언어 사양을 참조하십시오.(예, 과거에는 컴파일러 버그가있었습니다.)

이러한 상호 작용 방식의 맛을 보려면이 예제를 고려하십시오.개인 내부 수업을 "누출"할 수 있습니다.이것은 일반적으로 경고입니다.

class Test {
    public static void main(final String ... args) {
        System.out.println(Example.leakPrivateClass()); // OK
        Example.leakPrivateClass().secretMethod(); // error
    }
}

class Example {
    private static class NestedClass {
        public void secretMethod() {
            System.out.println("Hello");
        }
    }
    public static NestedClass leakPrivateClass() {
        return new NestedClass();
    }
}

컴파일러 출력 :

Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
        Example.leakPrivateClass().secretMethod(); // error
                                  ^
1 error

일부 관련 질문 :

Package-Private 클래스 내부의 Java - 메서드 액세스 가능성?

출처:https://stackoverflow.com/questions/215497/what-is-the-difference-between-public-protected-package-private-and-private-in