各位看客,今天我們來討論關於java中存取修飾符的相關問題,這也是面試的常見問題。
簡單來說,存取修飾符是程式碼的書寫者為了區分何時可存取程式碼,什麼時候不能存取程式碼而生的。 java裡面存取限制分為友善(即所謂的預設型),public,private,protected四類。
今天我們來看看其中比較難區分的兩大類,即友善型和protected。
先來看友善型,friendly。當我們在成員前面什麼修飾符都不加時,則該成員的訪問級別就為默認級別,那麼此時,與該class在同一個包下的其他的class可訪問這些成員,而不同包下的class則無法存取這些成員,如下:
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(); } }
當然,各位看官可能會碰到一種情況,就是在未指定package 的時候,不同文件夾內的class文件可以互相調用其友好型成員,原因則在於未指定套件時,所有檔案預設屬於預設套件,故而可以互相呼叫友善成員。
接著,我們來看看protected類型。這種類型與友善型(即預設型)很相似,唯一差異體現在繼承上面。簡單來說,只要class檔案不屬於同一個套件內(包含繼承情況),其他的class檔案都無法存取友善的成員;但class繼承的時候,不論是否屬於同一個套件內,在繼承情況下,子類別可以存取父類別的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); } }