클래스를 다음과 같이 정의 할 수없는 이유는 무엇 protected
입니까?
나는 우리가 할 수 없다는 것을 알고 있지만 왜? 특정한 이유가 있어야합니다.
클래스를 다음과 같이 정의 할 수없는 이유는 무엇 protected
입니까?
나는 우리가 할 수 없다는 것을 알고 있지만 왜? 특정한 이유가 있어야합니다.
답변:
말이되지 않기 때문입니다.
보호 된 클래스 멤버 (메서드 또는 변수)는 하위 클래스에서도 액세스 할 수 있다는 점을 제외하면 package-private (기본 가시성)와 같습니다.
Java에는 '서브 패키지'또는 '패키지 상속'과 같은 개념이 없기 때문에 보호되는 클래스 또는 패키지 전용을 선언하는 것은 동일합니다.
하지만 중첩 및 내부 클래스를 protected 또는 private으로 선언 할 수 있습니다.
open
현재 패키지 외부에서 서브 클래 싱을 허용하는 Kotlin에서 ( protected
반대 기본값으로 Java에서이를 방지하는 것을 상상할 수 있음).
아시다시피 기본은 패키지 수준 액세스를위한 것이고 보호는 패키지 수준과 비 패키지 클래스를위한 것이지만이 클래스를 확장합니다 (여기서 주목할 점은 클래스가 보이는 경우에만 확장 할 수 있다는 것입니다!). 다음과 같이합시다.
이 클래스가 소수의 클래스로만 하위 클래스로 분류되는 것을 제한 할 수있는 방법이 없기 때문에 (패키지 / 패키지 외부에서 사용 가능한 모든 클래스 중 소수의 클래스에서만 상속되는 클래스를 제한 할 수 없습니다) 보호 된 액세스 지정자를 사용하지 않습니다. 최고 수준의 수업. 따라서 허용되지 않습니다.
@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 (명시 적 수정 자 없음).
보호 된 필드를 정의하면 상속을 통해서만 패키지 외부뿐만 아니라 패키지 내부에서도 해당 필드에 액세스 할 수 있습니다 (하위 클래스 내부에서만).
따라서 클래스를 보호하도록 허용하면 패키지 내부에서 매우 쉽게 액세스 할 수 있지만 패키지 외부에서 해당 클래스에 액세스하려면 먼저이 클래스가 정의 된 해당 엔티티를 패키지로 확장해야합니다.
그리고 패키지를 확장 할 수 없기 때문에 (가져올 수 있음), 보호 된 클래스를 정의하면 우리가 이미 할 수있는 기본값으로 정의하는 것과 비슷하게 다시 package-private가됩니다. 따라서 private 클래스를 정의하는 이점은 없습니다.
자세한 내용 은 외부 Java 클래스가 개인용이거나 보호 될 수없는 이유를 읽어보십시오.
보호는 공개와 유사하지 않습니다. 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
}
"protected"동작 = "default"동작 + "모든 패키지의 모든 하위 클래스에서 사용".
어쨌든 우리는 클래스에 대한 기본 액세스 수정자를 가지고 있지만 보호 된 액세스 수정 자에서 얻을 수있는 유일한 이점은 다음과 같습니다.-서브 클래 싱을 통해 모든 패키지에서 사용합니다. 그러나 하위 클래스의 경우 상위 "보호 된"클래스의 가시성은 비공개입니다. 따라서 액세스 할 수 없습니다. 기본적으로 보호 된 최상위 클래스가있는 경우 하위 클래스를 만들어 외부 클래스에 액세스 할 수 없습니다. 따라서 최상위 클래스에 대한 보호는 의미가 없습니다.
@ Akash5288의 대답은 나에게 의미가 없습니다.
모든 클래스가 하위 클래스에 허용되면 공용 액세스 지정자와 유사합니다.
이 클래스가 소수의 클래스로만 하위 클래스로 분류되는 것을 제한 할 수있는 방법이 없기 때문에 (패키지 / 패키지 외부에서 사용 가능한 모든 클래스 중 소수의 클래스에서만 상속되는 클래스를 제한 할 수 없습니다) 보호 된 액세스 지정자를 사용하지 않습니다. 최고 수준의 수업. 따라서 허용되지 않습니다.
그런 다음 동일한 논리를 보호 된 메서드 및 변수에 적용 할 수 있으며 "공용과 유사"합니다. 패키지 외부의 모든 클래스는 공용 클래스를 확장하고 보호 된 메서드를 사용할 수 있습니다. 메서드와 변수를 확장 클래스로 제한하는 것은 괜찮지 만 전체 클래스를 제한하는 것은 왜 좋지 않습니까? "공개와 유사"는 "공개와 동일"이 아닙니다. 내 해석은 보호 된 메서드를 허용하는 것이 좋기 때문에 보호 된 클래스를 허용하는 것이 완벽하다는 것입니다.
"액세스 / 볼 수없는 클래스는 확장 할 수 없습니다"라는 대답이 더 논리적입니다.
이 질문에 의미가있는 것은 JVM이 C (Sun JVM) 및 C ++ (oracle JVM)로 작성되었으므로 컴파일하는 동안 Java 파일에서 .class 파일을 만들고 Protected 키워드로 클래스를 선언하면 그러면 JVM에 의해 액세스되지 않습니다.
보호 된 클래스가 JVM에 의해 액세스되지 않는 이유는 보호 된 필드가 동일한 패키지 내에서 또는 상속을 통해서만 다른 패키지에 액세스 할 수 있고 JVM이 will 클래스를 상속하는 방식으로 작성되지 않았기 때문입니다. 이것이이 질문을 만족시키기를 바랍니다 :)
마찬가지로 최상위 클래스는 비공개가 될 수 없습니다. 아래와 같이 설명 :
그래서 우리가 private 클래스를 정의한다면, 그 클래스는 그것이 정의 된 엔티티 내에서만 액세스 할 수있을 것입니다.
따라서 클래스에 대한 개인 액세스를 정의하면 기본 키워드가 이미 우리를 위해 수행하는 동일한 패키지 내에서 액세스 할 수 있으므로 클래스 개인을 정의하는 이점이 없습니다.
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
}