1. 程式人生 > >子類不能對父類private方法重寫

子類不能對父類private方法重寫

看到這樣一段程式碼

public class A {
    private void print() {
        System.out.println("A");
    }
    public static void main(String[] args) {
        A a = new B();
        a.print();
        B b = new B();
        b.print();
        new B().print();
    }
}

class B extends A {
    public void print
() { System.out.println("B"); } }

結果是
A
B
B
在java中,private的變數和方法對在類外是不可見的,當然更談不上重寫,B類中看似是重寫了父類A中的print方法,但由於父類中為private,所以B類中的print與A類中的print方法並無任何關係,可以認為是一個全新的方法。
舉個可能不恰當的例子,繼承時,父類方法在能被子類“看到”的情況下,父類的方法可以想象成直接被copy到了子類中,如果子類不想要用這個父類方法的實現,就要去重寫,相當於覆蓋掉了copy過來的方法,那怎麼就算覆蓋呢?
方法的作用,就算通過呼叫某個方法,會達到一些效果或者得到一(個)些值,在重寫這個概念中,子類不想要父類方法的達到的效果或者值,就要去修改,即覆蓋。所以覆蓋也就必須是方法引數,方法名,返回值都要和父類相同才能算是覆蓋。設想,如果三個要素任一個不符合,就會產生一個和想要覆蓋的那個方法不同的新方法,這個新方法是屬於當前子類的,原來本想覆蓋的那個類也沒有被覆蓋,依舊存在。(在更改的引數的情況下會成為過載,在只改變了返回值的情況下會報錯,具體請檢視過載的內容)
再回到這個程式碼,父類中的方法是private的,即子類是“看不到”的,所以也就沒有被“copy”到子類中,所以看似是重寫,實際上是一個屬於子類的新的方法,只不過“恰好”和父類中的方法重名了。
再想多型的要求,子類自己新增的方法在多型的情況下是不能使用的,是不可見的,所以當呼叫print方法時,編譯器看到子類沒有父類中的那個方法或者其重寫,就會選擇呼叫父類的方法。如果將父類的private改為高一級的可視性,子類就可以“看到”了,也就“copy”過來了,輸出為
B
B
B