Java繼承,重寫方法時改變方法的訪問權限


  java中的方法天生具有繼承多態特性,這點與C++有很大不同(需要在父類方發上加virtual關鍵字),但用起來確實方便了許多。

最簡單的繼承多態

  聲明一個接口BaseIF,只包含一個方法聲明

public interface BaseIF {
    void Access();
}

  一個基類Base,基類實現了BaseIF接口,Access會調用Base類的public函數test()(實現類最好不要有自己的public函數,public函數應提到接口中,這里是為了說明問題方便)

public class Base implements BaseIF {
    public void Access(){
        test();
    }

    public void test(){
        System.out.println("test in Base");
    }
}

  一個派生類Derived,派生類重寫test(),並保持test()的訪問權限保持不變,依然為public

public class Derived extends Base {
    //@Override
    public void test(){
        System.out.println("test in Derived");
    }
}

  Demo入口測試代碼

public class Main {

    public static void main(String[] args) {
        BaseIF face = new Derived();
        face.Access();
    }
}

  代碼運行結果為:

  表明實際調用的test()方法來自Derived類,這便是繼承多態的運行方式。

降低派生類中test方法的訪問權限

  將Derived類中test()的訪問權限改為protect或者private,這時IDE會報編譯錯誤,子類重寫父類方法時,不可以降低方法的可訪問性。

   

public class Derived extends Base {
    @Override
    protected void test(){
        System.out.println("test in Derived");
    }
}

  這一點其實很好理解,將測試代碼寫成下面這樣。假如可以在Derived中降低test()的訪問權限,那么base.test()應該調用基類的test()方法還是Derived類的?

  假如調用Base類的test(),那么子類重寫test()變沒有什么意義了;假如調用Derived類的,就會出現一個問題,Derived類的test()是protect方法,無法在類外部調用,假如通過基類可以調用派生類的protect或private方法,權限訪問控制變出現了漏洞,所以最好的處理方式就是禁止在派生類中降低重寫方法的可訪問性

public class Main {

    public static void main(String[] args) {
        Base base = new Derived();
        base.test();
    }
}

  

提升派生類中test方法的訪問權限

將Base類中test()的訪問權限改為protect,將Derived類中test()的訪問權限改為public,這時程序可以正確執行,說明可以在派生類中提升test()方法的可訪問性。

public class Base implements BaseIF {
    public void Access(){
        test();
    }

    protected void test(){
        System.out.println("test in Base");
    }
}
public class Derived extends Base {
    @Override
    public void test(){
        System.out.println("test in Derived");
    }
}

但有一點需要注意的是,如果Base中test()為private,那么在Derived中是看不到Base的test()的。這時Derived中如果也添加test()方法(無論訪問權限是什么),都不屬於重寫Base的test()方法,Derived的test()方法只屬於Derived類本身,而這時也無法實現多態。舉例:

public class Base implements BaseIF {
    public void Access(){
        test();
    }

    private void test(){
        System.out.println("test in Base");
    }
}
public class Derived extends Base {
    //@Override
    public void test(){
        System.out.println("test in Derived");
    }
}
public class Main {

    public static void main(String[] args) {
        BaseIF face = new Derived();
        face.Access();
    }
}

運行結果:

test in Base


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM