之前搞錯了,變量沒有“重寫”一說,只有方法才能被“重寫”。如果我們在子類中聲明了一個和父類中一樣的變量,那么實際的情況是,子類的內存堆中會有類型和名字都相同的兩個變量。
現在考慮一種情況,如下所示,我們在子類中聲明一個名字與父類中變量一樣,但是類型不同的變量i(一個int,一個double),同時我們在父類中有一個print()打印i,那么當我們從子類的對象中調用這個print()時,他到底會打印哪一個i?
class SuperClass { public int i; SuperClass(){ i=10; System.out.println("SuperClass() is construted."); } public void print(){ System.out.println("the i in SuperClass: "+i); } } class SubClass extends SuperClass { public double i; SubClass(){ i=20.0; System.out.println("SubClass() is constructed."); } public void printSub(){ System.out.println("the i in SubClass: "+i); } } public class TestDemo { public static void main(String[] args) { SubClass sub=new SubClass(); System.out.println("sub.i is: "+sub.i); sub.printSub(); sub.print(); } } 輸出結果為: SuperClass() is construted. SubClass() is constructed. sub.i is: 20.0 the i in SubClass: 20.0 the i in SuperClass: 10
我們很清楚,如果在子類中重新聲明一個同樣的print()函數,父類的print()函數就會被覆蓋掉,這時print()輸出的是在子類中定義的double i=20.0,所以對這種情況我沒有討論。
從輸出結果來看,通過子類SubClass的對象sub訪問到的i的值為double i=20.0,然而通過子類對象調用在父類中定義的print(),打印的仍然是父類中的int i=10,如何解釋這種情況?
現在我們把SubClass進行修改:
class SubClass extends SuperClass { public int i; SubClass(){ i=20; System.out.println("SubClass() is constructed."); } public void printSub(){ System.out.println("the i in SubClass: "+i); } } /*測試結果為*/ SuperClass() is construted. SubClass() is constructed. sub.i is: 20 the i in SubClass: 20 the i in SuperClass: 10
我們看到,就算是在子類SubClass中聲明了一個完全一樣的i,通過子類對象調用在父類中定義的print(),打印的仍然是父類中的int i=10。說明了兩點:子類仍然含有父類中的i,父類的方法不能操作子類中的變量。
接下來,我再進行改動:
class SubClass extends SuperClass { public int i; SubClass(){ i=20; System.out.println("SubClass() is constructed."); } public void print(){ System.out.println("the i in SubClass: "+i); } } class TestDemo { public static void main(String[] args) { SubClass sub=new SubClass(); System.out.println("sub.i is: "+sub.i); System.out.println("((SuperClass)sub).i is:"+((SuperClass)sub).i); System.out.println("\n sub.print() is :"); sub.print(); System.out.println("((SuperClass)sub).print() :"); ((SuperClass)sub).print(); } } 輸出結果: SuperClass() is construted. SubClass() is constructed. sub.i is: 20 ((SuperClass)sub).i is:10 sub.print() is : the i in SubClass: 20 ((SuperClass)sub).print() : the i in SubClass: 20
改動后,子類父類中都有int i,他們的值不同;也都有完全一樣的print()來打印i。看看結果,父類的i仍然存在子類的內存中,只是它被”隱藏“起來了,可以通過向上轉型訪問到。而父類中的print()方法,卻訪問不到了,被完全覆蓋掉了。