클래스를 보호 된 것으로 정의 할 수없는 이유는 무엇입니까?


89

클래스를 다음과 같이 정의 할 수없는 이유는 무엇 protected입니까?

나는 우리가 할 수 없다는 것을 알고 있지만 왜? 특정한 이유가 있어야합니다.


3
그것은 무엇을 할 당신이 클래스가 보호 선언하면?

1
:이 당신을 위해 무엇을 찾고있는 생각 stackoverflow.com/questions/2534733/java-protected-classes D :
dewijones92

2
왜 외부 클래스를 보호 할 수 없는지 말해 봅시다. 내부 클래스를 보호 할 수 있습니다.
Number945

답변:


101

말이되지 않기 때문입니다.

보호 된 클래스 멤버 (메서드 또는 변수)는 하위 클래스에서도 액세스 할 수 있다는 점을 제외하면 package-private (기본 가시성)와 같습니다.
Java에는 '서브 패키지'또는 '패키지 상속'과 같은 개념이 없기 때문에 보호되는 클래스 또는 패키지 전용을 선언하는 것은 동일합니다.

하지만 중첩 및 내부 클래스를 protected 또는 private으로 선언 할 수 있습니다.


> Java에는 '서브 패키지'또는 '패키지 상속'과 같은 개념이 없기 때문에 보호되는 클래스 또는 패키지-개인을 선언하는 것은 동일합니다. 보호되는 클래스가 패키지 개인과 동일한 가시성을 갖는 이유는 무엇입니까? 공개와 같지 않습니까? 감사.
yaromir

@Nikita Ryback subPackage 또는 package-inheritance가 무엇인지 설명해 주시겠습니까? 나는 여전히 최상위 클래스에서 protected가 사용되는 이유를 명확하지 않습니다. 예를 들어 설명하면 좋을 것입니다.
App Kart

클래스 멤버 를 보호 된 것으로 선언하면 가시성은 동일한 패키지 (패키지 액세스라고 함) 및 Subclassess의 클래스 입니다. 다른 패키지의 외부 클래스에서 액세스하려고하면이 보호 된 메서드 멤버가 표시되지 않습니다.
kelgwiin 2015-06-17

@kelgwiin 클래스와 멤버의 액세스 수정자를 혼합해서는 안된다고 생각합니다. 둘이 다르기 때문입니다. 클래스는 스스로를 public 또는 default로 수정할 수 있지만 멤버는 public, private, protected 및 default로 수정할 수 있습니다.
sharhp

2
"말이 안 되니까"-다소 대담한 말입니다. 그것은 자바에 정의되지 않은,하지만 비슷한 일이 않습니다 존재; 예를 들어 open현재 패키지 외부에서 서브 클래 싱을 허용하는 Kotlin에서 ( protected반대 기본값으로 Java에서이를 방지하는 것을 상상할 수 있음).
Raphael

41

아시다시피 기본은 패키지 수준 액세스를위한 것이고 보호는 패키지 수준과 비 패키지 클래스를위한 것이지만이 클래스를 확장합니다 (여기서 주목할 점은 클래스가 보이는 경우에만 확장 할 수 있다는 것입니다!). 다음과 같이합시다.

  • 보호 된 최상위 클래스는 패키지의 클래스에 표시됩니다.
  • 이제 패키지 (서브 클래스) 외부에서 보이게하는 것은 약간 혼란스럽고 까다 롭습니다. 보호 된 클래스를 상속하려면 어떤 클래스가 허용되어야합니까?
  • 모든 클래스가 하위 클래스에 허용되면 공용 액세스 지정자와 유사합니다.
  • 없으면 기본값과 유사합니다.

이 클래스가 소수의 클래스로만 하위 클래스로 분류되는 것을 제한 할 수있는 방법이 없기 때문에 (패키지 / 패키지 외부에서 사용 가능한 모든 클래스 중 소수의 클래스에서만 상속되는 클래스를 제한 할 수 없습니다) 보호 된 액세스 지정자를 사용하지 않습니다. 최고 수준의 수업. 따라서 허용되지 않습니다.


3
"이제 보호 된 클래스를 패키지 (subclasses) 외부에서 볼 수있게 만드는 것은 약간 혼란스럽고 까다 롭습니다. 보호 된 클래스를 상속하도록 허용해야하는 클래스는 무엇입니까? 그리고 모든 클래스가 서브 클래스에 허용되면 공용 액세스 지정자와 유사합니다." 정말 날 :) 보호 클래스가 이해가되지 않는 이유에 대한 문제를 이해하는 데 도움
user1338998


3

@Nikita Rybak 답변 에는 좋은 점이 있지만 세부 정보가 부족합니다. 나 자신을 깊이 생각하지 않고는 아이디어를 얻을 수 없습니다. 다음은 내가 생각한 것이므로 이제 그 이유를 완전히 이해해야합니다.

4 개의 액세스 수정 자, 첫 번째 수준이 공개이고 4 단계가 비공개라고 가정합니다 (이 표에 따라 을 순서대로 기준으로 함). 가장 먼저 알아야 할 것은 클래스가 최상위 수준에서 개인으로 정의 될 수없는 이유입니다.

따라서 "private class foo"(정의 된 개인 멤버, 즉 클래스 자체가 멤버)가 허용하는 경우 외부 (멤버를 포함하는)는 무엇입니까? 파일 범위? 아니요, 단일 파일의 여러 클래스도 별도의 클래스 파일로 컴파일되므로 파일 외부는 무의미합니다. 그래서 외부는 패키지 입니다. 그러나 세 번째 수준의 기본 액세스 수정자는 이미 "package-private "를 의미합니다 . 따라서 4 단계 개인 액세스 수정자는 사용 / 허용되지 않습니다.

그러나 중첩 된 개인 클래스 는 직접 외부가 패키지가 아닌 클래스이기 때문에 허용됩니다. :

class PrivateNestedMain {
    private static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

이제 "protected class foo"가 허용한다면 어떨까요? 보호되는 주요 특성 은 하위 클래스이므로 outer (package)는 (최대 범위로 인해 선택 사항이지만) 하위 클래스의 스타일을 제공해야합니다 ( 예 : 하위 패키지 또는 package A extends package B).하지만 우리는 그런 것을 알지 못합니다. 따라서 protected는 외부가 패키지 인 최상위 수준 (즉, 하위 패키지가 없음)에서 전체 잠재력 (주 범위는 하위 클래스 전체)을 사용할 수 없지만, protected는 외부가 class () 인 중첩 클래스에서 전체 잠재력을 사용할 수 있습니다. 즉, 하위 클래스가 될 수 있습니다) :

class ProtectedNestedMain {
    protected static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

참고 위는 서브 클래스 전체에 도달 할 수없는 때문에 단순히 수단의 어떤 외부 서브 클래스, 때문에 "잠재력을 사용할 수 없습니다"라고 그 사실 수 있도록 할 수 있습니다 보호를 , 그것을 피하기 위해 선택의 단지 문제는 패키지의 작업을 중복하지 -private 외부가 하위 클래스가 아닌 경우 아래를 참조하십시오.

내 혼란은 주로 https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html 의 유명한 테이블로 인해 발생합니다 .

여기에 이미지 설명 입력

1 단계 (공개)와 3 단계 (패키지-비공개)가 허용된다면 어떻게 도대체 2 단계 (보호) 사이가 허용되지 않습니까?

대중 지원 하위 클래스는 오해하기 쉽습니다. 이 표를 읽는 올바른 방법은

외부에 하위 클래스 기능이있는 경우 공개 지원 하위 클래스.

동일한 오해의 소지가있는 package-private에 적용되고 package-private가 하위 클래스를 지원하지 않는다 ( 셀의 N )는 하위 클래스 개념이 외부에 적용됨을 의미하지 않습니다.

즉 , 하위 클래스 기능을 외부에서 사용할 수없는 경우 하위 클래스 열을 무시해야합니다 .

여기에 이미지 설명 입력

지금 볼 수 있듯이 protected와 package-private는 이제 동일한 수준 ( YYN )이므로 중간 수준이 허용되지 않는 이유에 대해 더 이상 혼동하지 않습니다. 전반적으로, 자바는 이상 (혼란을 방지하기 위해 보호 민간 패키지 선택 은 선택의 문제이다 , 그러나 보호 의 주요 특성이 우수한 패키지 개인 있도록, 서브 클래스), 그리고 결과 만이 액세스 한정자는 최고 수준에 허용 :

최상위 수준-public 또는 package-private (명시 적 수정 자 없음).


3

보호 된 필드를 정의하면 상속을 통해서만 패키지 외부뿐만 아니라 패키지 내부에서도 해당 필드에 액세스 할 수 있습니다 (하위 클래스 내부에서만).

따라서 클래스를 보호하도록 허용하면 패키지 내부에서 매우 쉽게 액세스 할 수 있지만 패키지 외부에서 해당 클래스에 액세스하려면 먼저이 클래스가 정의 된 해당 엔티티를 패키지로 확장해야합니다.

그리고 패키지를 확장 할 수 없기 때문에 (가져올 수 있음), 보호 된 클래스를 정의하면 우리가 이미 할 수있는 기본값으로 정의하는 것과 비슷하게 다시 package-private가됩니다. 따라서 private 클래스를 정의하는 이점은 없습니다.

자세한 내용 은 외부 Java 클래스가 개인용이거나 보호 될 수없는 이유를 읽어보십시오.


3
제휴 관계를 공개하고 게시를 통해 사이트를 홍보하는 방법으로 사이트를 사용하지 마십시오. 좋은 답변어떻게 작성합니까?를 참조하십시오 . .

1

보호는 공개와 유사하지 않습니다. Protected는 패키지 수준 액세스를 모두 가지며 상속을 통해서만 패키지 외부에서 액세스 할 수 있습니다. 클래스가 패키지 외부에서 A라고 말하면 다른 패키지의 클래스를 상속합니다 (INHERITANCE를 사용하여 보호 된 메서드 사용).이 클래스 B의 메서드에 액세스 할 수 있습니다. 보호 된 메소드가 있지만이 클래스에서 파생 된 하위 클래스는 A가 보호 된 메소드에 액세스 할 수 없습니다.

예:

package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}

0

"protected"동작 = "default"동작 + "모든 패키지의 모든 하위 클래스에서 사용".

어쨌든 우리는 클래스에 대한 기본 액세스 수정자를 가지고 있지만 보호 된 액세스 수정 자에서 얻을 수있는 유일한 이점은 다음과 같습니다.-서브 클래 싱을 통해 모든 패키지에서 사용합니다. 그러나 하위 클래스의 경우 상위 "보호 된"클래스의 가시성은 비공개입니다. 따라서 액세스 할 수 없습니다. 기본적으로 보호 된 최상위 클래스가있는 경우 하위 클래스를 만들어 외부 클래스에 액세스 할 수 없습니다. 따라서 최상위 클래스에 대한 보호는 의미가 없습니다.


0

보호됨 : 패키지 수준에만 표시 *.

클래스는 보호 정의되어 있습니다 ---> 외부 패키지에서 확장 할 수 없습니다 (표시되지 않음).

이 후 확장 할 수없는 경우 그리고으로 유지하는 것이 의미가 보호 한 후가 될 것입니다 때문에, 기본 허용 액세스 입니다.

개인 정의 클래스 에도 동일하게 적용됩니다 .

참고 : 중첩 또는 내부 클래스는 protected 또는 private 로 정의 할 수 있습니다 .

* : 보호 된 키워드를 탐색 하십시오.이 답변에 대해 간결하게 만들었습니다.


0

@ Akash5288의 대답은 나에게 의미가 없습니다.

모든 클래스가 하위 클래스에 허용되면 공용 액세스 지정자와 유사합니다.

이 클래스가 소수의 클래스로만 하위 클래스로 분류되는 것을 제한 할 수있는 방법이 없기 때문에 (패키지 / 패키지 외부에서 사용 가능한 모든 클래스 중 소수의 클래스에서만 상속되는 클래스를 제한 할 수 없습니다) 보호 된 액세스 지정자를 사용하지 않습니다. 최고 수준의 수업. 따라서 허용되지 않습니다.

그런 다음 동일한 논리를 보호 된 메서드 및 변수에 적용 할 수 있으며 "공용과 유사"합니다. 패키지 외부의 모든 클래스는 공용 클래스를 확장하고 보호 된 메서드를 사용할 수 있습니다. 메서드와 변수를 확장 클래스로 제한하는 것은 괜찮지 만 전체 클래스를 제한하는 것은 왜 좋지 않습니까? "공개와 유사"는 "공개와 동일"이 아닙니다. 내 해석은 보호 된 메서드를 허용하는 것이 좋기 때문에 보호 된 클래스를 허용하는 것이 완벽하다는 것입니다.

"액세스 / 볼 수없는 클래스는 확장 할 수 없습니다"라는 대답이 더 논리적입니다.


0

이 질문에 의미가있는 것은 JVM이 C (Sun JVM) 및 C ++ (oracle JVM)로 작성되었으므로 컴파일하는 동안 Java 파일에서 .class 파일을 만들고 Protected 키워드로 클래스를 선언하면 그러면 JVM에 의해 액세스되지 않습니다.

보호 된 클래스가 JVM에 의해 액세스되지 않는 이유는 보호 된 필드가 동일한 패키지 내에서 또는 상속을 통해서만 다른 패키지에 액세스 할 수 있고 JVM이 will 클래스를 상속하는 방식으로 작성되지 않았기 때문입니다. 이것이이 질문을 만족시키기를 바랍니다 :)

마찬가지로 최상위 클래스는 비공개가 될 수 없습니다. 아래와 같이 설명 :

그래서 우리가 private 클래스를 정의한다면, 그 클래스는 그것이 정의 된 엔티티 내에서만 액세스 할 수있을 것입니다.

따라서 클래스에 대한 개인 액세스를 정의하면 기본 키워드가 이미 우리를 위해 수행하는 동일한 패키지 내에서 액세스 할 수 있으므로 클래스 개인을 정의하는 이점이 없습니다.


0

protected는 동일한 패키지의 모든 클래스와 다른 패키지에있는 경우에도 하위 클래스에서 멤버에 액세스 할 수 있음을 의미합니다.

예:

package a;
class parent{
 protected void p();
}
package b;
import a.p;
class child extends parent{
  //you can access method which is protected in the parent in the child 
}
class another extends child {
 //here you can not access the protected method 
}

0

protected에 의해 외부 클래스가 선언되면 동일한 패키지와 하위 클래스이지만 다른 패키지에서만 클래스에 액세스 할 수 있기를 원한다고 생각합니다. 그러나 보호 된 클래스에 대한 하위 클래스를 만들 수 없습니다. "class Dog extends Animal"을 작성할 때 보호 된 "Animal"은 해당 하위 클래스에서만 액세스 할 수 있기 때문에 "Dog"는 "Animal"하위 클래스가 아닙니다. .

따라서 보호 된 외부 클래스는 (기본) 외부 클래스와 동일합니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.