protected這個修飾符,各大參考書都會這樣說:訪問權限爲類內,包內和子類,所以在父類中定義的方法和成員變量若是爲protected修飾的,是能夠在不一樣包中的子類進行訪問的,示例代碼以下:spa
1 package cn.tedu.object.a; 2 3 public class A { 4 5 protected void m(){ 6 System.out.println("A m~~~"); 7 } 8 9 }
1 package cn.tedu.object.b; 2 3 import cn.tedu.object.a.A; 4 5 public class B extends A { 6 void callM() { 7 m(); 8 super.m(); 9 B b = new B(); 10 b.m(); 11 } 12 }
如上代碼所示,class B繼承了class A,可是兩個類位於a、b兩個不一樣的包中,此時class B能夠直接訪問class A中的protected修飾的方法。一共有三種方法訪問:code
第一種爲第7行,直接調用;對象
第二種爲第8行,加super關鍵字;其實前兩種是等效的。blog
第三種爲第九、10行,實例化一個對象進行調用。繼承
那麼問題來了,若是說在b包中新建一個class C,而且有以下代碼,會報錯嗎?class
1 package cn.tedu.object.b; 2 3 import cn.tedu.object.a.A; 4 5 public class C extends A { 6 7 void callM() { 8 m(); 9 super.m(); 10 B b = new B(); 11 b.m(); //The method m() from type A is not visible 12 } 13 14 }
會報錯!那爲何會報錯呢?import
由於b.m()這種調用屬於子類對象調用,並非子類調用。變量
這個是很是須要引發注意的。所以,當建立子類對象調用父類的protected成員變量時,必需要注意:子類對象和子類是對應的!object
經過這個例子其實也能夠看出來,當一個包外子類繼承保護成員時,該成員在這個子類內實際上變爲私有。權限
事實上,除了以上三種調用父類protected成員變量的方法外,其他都是會報錯的!
包括用超類實例去訪問。代碼以下:
1 package cn.tedu.object.b; 2 3 import cn.tedu.object.a.A; 4 5 public class B extends A { 6 7 void callM() { 8 A a=new A(); 9 a.m(); //The method m() from type A is not visible 10 } 11 12 }
一樣的,會報錯!所以,能夠獲得結論:
包外子類有權訪問超類成員,它指子類繼承該成員,然而,這並不意味着包外子類可以使用超類實例的引用訪問該成員。