시청자 여러분, 오늘은 인터뷰에서 자주 묻는 질문이기도 한 자바의 접근 한정자 관련 이슈에 대해 이야기해보겠습니다.
간단히 말하면 코드 작성자는 코드에 액세스할 수 있는 시기와 코드에 액세스할 수 없는 시기를 구별하기 위해 액세스 한정자를 만듭니다. Java의 액세스 제한은 친화적(소위 기본 유형), 공개, 비공개 및 보호의 네 가지 범주로 나뉩니다.
오늘은 구별하기 어려운 두 가지 범주, 즉 친근함과 보호에 대해 살펴보겠습니다.
먼저 친근함부터 살펴보겠습니다. 멤버 앞에 수식자를 추가하지 않으면 해당 멤버의 액세스 수준이 기본 수준이 됩니다. 이때 해당 클래스와 동일한 패키지에 있는 다른 클래스는 이러한 멤버에 액세스할 수 있지만, 다른 패키지 클래스에 있는 클래스에서는 액세스할 수 없습니다. 이러한 멤버는 다음과 같습니다.
package com.a1; /** * A属于 com.a1 这个包 * @author Will * */ public class A { //成员均为默认访问级别 int i; String str; void print(){ System.out.println("i:"+i+";str:"+str); } }
package com.a1; /** * testA1属于com.a1 * @author Will * */ public class testA1 { public static void main(String[] args) { //由于testA1与A属于同一个包下,所以可以访问友好型的成员 A a=new A(); System.out.println(a.i); System.out.println(a.str); a.print(); } }
package com.b1; import com.a1.A; /** * testA2属于com.b1 * * @author Will * */ public class testA2 { public static void main(String[] args) { // 由于testA2与A不属于同一个包下,所以不能访问友好型的成员 // 去掉注释符会报错 A a = new A(); //System.out.println(a.i); //System.out.println(a.str); //a.print(); } }
물론 독자는 패키지가 지정되지 않은 경우 다른 폴더의 파일 클래스 파일이 각각을 호출할 수 있는 상황에 직면할 수 있습니다. 그 이유는 패키지를 지정하지 않으면 기본적으로 모든 파일이 기본 패키지에 속하므로 서로의 친숙한 멤버를 호출할 수 있기 때문입니다.
다음으로 protected 유형을 살펴보겠습니다. 이 유형은 친숙한(즉, 기본) 유형과 매우 유사하며 유일한 차이점은 상속입니다. 간단히 말해서, 클래스 파일이 동일한 패키지(상속 포함)에 속하지 않는 한 다른 클래스 파일은 친숙한 멤버에 액세스할 수 없지만 클래스가 상속되면 동일한 패키지에 속하는지 여부에 관계없이 상속의 경우 하위 클래스는 상위 클래스의 보호된 멤버에 액세스할 수 있습니다.
package com.a1; /** * A属于 com.a1 这个包 * i,str为友好型 * j,str1为protected型 * @author Will * */ public class A { int i; String str; protected int j; protected String str1; public A(){ } void print(){ System.out.println("i:"+i+";str:"+str); } protected void print(int k){ System.out.println("j:"+j+";str1:"+str1); } }
package com.a1; /** * testA1属于com.a1 * @author Will * */ public class testA1 { public static void main(String[] args) { //由于testA1与A属于同一个包下,所以可以访问友好型的成员 //也可以访问protected类型成员 A a=new A(); System.out.println(a.i); System.out.println(a.str); System.out.println(a.j); System.out.println(a.str1); a.print(); a.print(1); } }
package com.b1; import org.junit.Test; import com.a1.A; public class ExtendsA extends A{ @Test public void test(){ ExtendsA extendsA=new ExtendsA(); //当不再同一个包且继承情况下,不可调用父类友好型成员 //去掉注释会报错 //System.out.println(extendsA.i); //System.out.println(extendsA.str); //extendsA.print(); //当不再同一个包且继承情况下,可调用父类protected型成员 System.out.println(extendsA.j); System.out.println(extendsA.str1); extendsA.print(1); } }