一提到訪問控制符protected,即使是初學者一般都會很自信的認爲自己在這方面的理解沒有問題。那好,我們提一個問題出來看看…
問題提出:
請看下面兩端代碼,其中包B中的貓和鼠都繼承了動物類。
- package testa;
- public class Animal {
- protected void crowl(String c){
- System.out.println(c);
- }
- }
代碼2:
- package testb;
- import testa.Animal;
- class Cat extends Animal
- {
- }
- public class Rat extends Animal{
- public void crowl(){
- this.crowl("zhi zhi"); //沒有問題,繼承了Animal中的protected方法——crowl(String)
- Animal ani=new Animal();
- ani.crowl("animail jiaojiao"); //wrong, The method crowl(String) from the type Animal is not visible
- Cat cat=new Cat();
- cat.crowl("miao miao"); //wrong, The method crowl(String) from the type Animal is not visible
- }
- }
既然,貓和鼠都繼承了動物類,那麼在鼠類的作用範圍內,看不到貓所繼承的crowl()方法呢?
癥結所在:
protected受訪問保護規則是很微妙的。雖然protected域對所有子類都可見。但是有一點很重要,子類只能在自己的作用範圍內訪問自己繼承的那個父類protected,而無法到訪問別的子類(同父類的親兄弟)所繼承的protected域和父類對象的protected域ani.crow1()。說白了就是:老鼠只能"zhi,zhi"。即使他能看見貓(可以在自己的作用域內創建一個cat對象),也永遠無法學會貓叫
也就是說,cat所繼承的crowl方法在cat類作用範圍內可見。但在rat類作用範圍內不可見,即使rat,cat是親兄弟也不行。
這就是爲什麼我們在用clone方法的時候不能簡單的直接將對象aObject.clone()出來的原因了。而需要在aObject.bObject=(Bobject)this.bObject.clone();
總之,當B extends A的時候,在子類B的作用範圍內,只能調用本子類B定義的對象的protected方法(該方法從父類A中繼承而來)。而不能調用其他A類(A 本身和從A繼承)對象的protected方法
另外:同包內均和派生類中可比默認[default|package](只包內能使用) 權限大一點。
如把上面代碼放到同一package 裏就可以訪問了。
- package com;
- import testa.Ani;
- class Animail {
- protected void crowl(String c){
- System.out.println(c);
- }
- }
- class Cat extends Animail{
- }
- public class Rat extends Animail{
- public void crowl(){
- crowl("zhi zhi"); //沒有問題,繼承了Animal中的protected方法——crowl(String)
- Animail ani=new Animail();
- ani.crowl("animail jiaojiao");
- Cat cat=new Cat();
- cat.crowl("miao miao"); //wrong, The method crowl(String) from the type Animal is not visible
- }
- public static void main(String[] args){
- Rat rat=new Rat();
- rat.crowl();
- }
- }
- zhi zhi
- animail jiaojiao
- miao miao