第三次動手動腦
(一)
通過 super 呼叫基類構造方法,必須是子類構造方法中的第一個語句。在呼叫子類構造方法之前,必須先呼叫基類構造方法。
(二)
為什麼子類的構造方法在執行之前,必須呼叫父類的構造方法?能不能反過來?為什麼不能反過來?
建構函式的主要作用是在定義物件時初始化物件,定義子類物件時會同時定義父類物件,然後呼叫父類構造方法將其初始化,再呼叫子類物件將其初始化,所以不能反過來。
(三)
package JavaApp; public class ExplorationJDKSource { /** * @param args */ publicstatic void main(String[] args) { System.out.println(new A()); } } class A{}
我們得到了一個奇特的執行結果: [email protected]
為什麼??
在編譯原始碼時,當遇到沒有父類的類時,編譯器會將其指定一個預設的父類(一般為Object),而虛擬機器在處理到這個類時,由於這個類已經有一個預設的父類了,main方法實際上呼叫的是:
public void println(Object x),這一方法內部呼叫了String類的valueOf方法。
valueOf方法內部又呼叫Object.toString方法:
public String toString()
{
return getClass().getName() +"@" + Integer.toHexString(hashCode());
}
hashCode方法是本地方法,由JVM設計者實現: public native int hashCode();所以出現上述結果。
(四)
package JavaApp; public class Fruit { public String toString() { return "Fruit toString."; } public staticvoid main(String args[]) { Fruit f=new Fruit(); System.out.println("f="+f); System.out.println("f="+f.toString()); } }
一個字串和一個物件“相加”,得到以下結果:
f=Fruit toString.
f=Fruit toString.
為什麼??
當一個字串和一個物件連線時,物件會隱式的呼叫其toString方法。所以兩個輸出結果一樣。
(五)
在子類中,若要呼叫父類中被覆蓋的方法,可以使用super關鍵字。
package JavaApp; class one { public void one() { System.out.println("這是父類!"); } } class two extends one { public void one() { System.out.println("這是子類!"); System.out.println("使用super關鍵字:"); super.one(); } } public class fugai { public static void main(String[] args) { // TODO Auto-generated method stub two a=new two(); a.one(); } }
執行結果:
這是子類!
使用super關鍵字:
這是父類!
(1)覆蓋方法的允許訪問範圍不能小於原方法。
(2)覆蓋方法所丟擲的異常不能比原方法更多。
(3)宣告為final方法不允許覆蓋。 例如,Object的getClass()方法不能覆蓋。
(4)不能覆蓋靜態方法。
(六)
下列語句哪一個將引起編譯錯誤?為什麼?哪一個會引起執行時錯誤?為什麼?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
package JavaApp; class Mammal{} class Dog extends Mammal {} class Cat extends Mammal{} public class TestCast { public static void main(String args[]) { Mammal m; Dog d=new Dog(); Cat c=new Cat(); //m=d; //d=m; //d=(Dog)m; //d=c; //c=(Cat)m; } }
子類物件可以賦給基類物件,基類物件賦給子類物件時必須強制轉換,同一父類派生下來的子類之間不可以賦值。
所以可以成立的有m=d; d=(Dog)m; c=(Cat)m;
(七)
package JavaApp; public class ParentChildTest { public static void main(String[] args) { Parent parent=new Parent(); parent.printValue(); Child child=new Child(); child.printValue(); parent=child; parent.printValue(); parent.myValue++; parent.printValue(); ((Child)parent).myValue++; parent.printValue(); } } class Parent{ public int myValue=100; public void printValue() { System.out.println("Parent.printValue(),myValue="+myValue); } } class Child extends Parent{ public int myValue=200; public void printValue() { System.out.println("Child.printValue(),myValue="+myValue); } }
執行結果:
Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201