1. 程式人生 > >動手動腦-4

動手動腦-4

類型 類的初始化 clas 必須 stc created best 調用方法 類對象

package 動手動腦;

public class 基類 {
     public 基類()
         {

                System.out.println("基類 Created.");
        
    }


        public 基類(String string) 
        {

                System.out.println("基類 Created.String:" + string);
        
     }

}
package 動手動腦;

public class 父類 extends 基類 {
    
public 父類() { super("Hello.Grandparent."); System.out.println("父類 Created"); //super("Hello.Grandparent."); } } package 動手動腦; public class 子類 extends 父類{ public 子類() { System.out.println("子類 Created"); } } package 動手動腦; public
class 測試 { public static void main(String args[]) { 子類 c = new 子類(); } }

當super在父類構造函數上面時,最終的運行結果為:

基類 Created.String:Hello.Grandparent.
父類 Created
子類 Created

先調用基類有參構造函數,輸出基類 Created.String:Hello.Grandparent.,然後再依次調用父類和子類構造函數。當super在父類構造函數的下面時,出現錯誤,程序無法運行。所以得出結論,用super調用基類的構造方法,必須是子類的第一個語句。

構造方法用於對基類的初始化。構造一個對象,先調用其構造方法,來初始化其成員函數和成員變量。子類擁有父的成員變量和成員方法,如果不調用,則從父類繼承而來的成員變量和成員方法得不到正確的初始化。

package 動手動腦;

public class 父類2 {
    
public  void sleeping() {
    System.out.println("父親在睡覺。");
}
}
package 動手動腦;

public class 子類2 extends 父類2{
    
public  void sleeping() {
    super.sleeping();
    System.out.println("孩子在睡覺。");
}
}
package 動手動腦;

public class 測試2 {
public static void main(String[] args) {
    
    子類2 z=new 子類2();
    z.sleeping();
}
}

這個程序的運行結果為:

父親在睡覺。
孩子在睡覺。

子類把父類的方法覆蓋,通過super關鍵字來調用父類中的方法。

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;

    }
}

通過運行我發現,當放開d=m這一行和d=c這一行的註釋之後,編譯出現錯誤,當放開c=(Cat)m這一行的註釋之後,運行出現錯誤。因為m是父類創建的對象,而d是子類創建的對象,所以當d=m時需要進行類型強制轉換,而沒有轉換會使編譯出現錯誤。d=c這一行出現錯誤的原因是不能讓同等地位的對象進行轉換。

package 動手動腦;

public class Child extends Parent {

    public int myValue=200;
    public void printValue() {
        System.out.println("Child.printValue(),myValue="+myValue);
    }
}
package 動手動腦;

public class Parent {
    public int myValue=100;
    public void printValue() {
        System.out.println("Parent.printValue(),myValue="+myValue);
    }
}
package 動手動腦;

public class ParentChildTest {
    public static void main(String[] args) {
        Parent parent=new Parent();
        parent.printValue();
        Child c=new Child();
        c.printValue();
        
        parent=c;
        parent.printValue();
        
        parent.myValue++;
        parent.printValue();
        
        ((Child)parent).myValue++;
        parent.printValue();
        
    }
}

這個程序運行之後的結果為:

Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201

前兩條結果不用解釋,第三條,parent=c; 將子類變量賦給基類變量,這樣就是體現了多態性,和Parent parent=new Child();的效果是一樣的,此時當對象parent引用方法時,引用的是子類的方法,而當此對象引用變量時,引用的是父類的變量,所以在parent.printValue();時,輸出的是子類中方法的輸出語句,而parent.myValue++;時,增加的是父類變量myValue的值,而子類中myValue的值不變,所以當此對象再次引用此方法時,輸出的仍是子類中此方法中的輸出語句,而myValue的值不變,當使用了強制類型轉換之後,((Child)parent).myValue++;此時(Child)parent就相當於是子類對象,引用變量myValue時,增加的是子類myValue的值,而調用方法之後,輸出子類方法中的輸出語句,而myValue得值發生變化。

動手動腦-4