1. 程式人生 > >Java中靜態屬性、靜態方法繼承重寫的那點破事

Java中靜態屬性、靜態方法繼承重寫的那點破事

public class A { 
    public static String staticStr = "A's static field";  
    public String nonStaticStr = "A's nonstatic field";  
    public static void staticMethod(){  
        System.out.println("A's static method");  
    }  
    public void nonStaticMethod(){  
        System.out.println("A's nonstatic method"
); } } public class B extends A{ public static String staticStr = "B's static field"; public String nonStaticStr = "B's nonstatic field"; public static void staticMethod(){ System.out.println("B's static method"); } } public class C extends A{ } public class
Test {
public static void main(String[] args) { C c = new C(); System.out.println(c.nonStaticStr); //A's nonstatic field System.out.println(c.staticStr); //A's static field c.staticMethod(); //A's static method System.out.println("-------------------------------"
); A c1 = new C(); System.out.println(c1.nonStaticStr); //A's nonstatic field System.out.println(c1.staticStr); //A's static field c1.staticMethod(); //A's static method // 以上這說明java中靜態屬性和靜態方法可以被繼承 System.out.println("-------------------------------"); B b = new B(); System.out.println(b.nonStaticStr); // B's nonstatic field System.out.println(b.staticStr); //B's static field b.staticMethod(); //B's static method System.out.println("-------------------------------"); A b1 = new B(); System.out.println(b1.nonStaticStr); //A's nonstatic field System.out.println(b1.staticStr); //A's static field b1.staticMethod(); //A's static method //b1.nonStaticStr 輸出的是父類的非靜態屬性,說明非靜態屬性不可以被重寫,不能實現多型 //b1.staticStr 輸出的是父類的靜態屬性,說明靜態屬性不可以被重寫,不能實現多型 //b1.staticMethod()輸出的是父類A的靜態方法,不是子類B改寫後的,所以沒有實現多型 //結論是:靜態屬性和靜態方法只是可以繼承沒有表現出多型性。 //因為靜態方法和靜態屬性沒有采用動態繫結。具體表現就是, //將子類例項向上轉型則會呼叫到基類中的靜態方法和屬性, //不轉型就呼叫子類自身的靜態方法和屬性。 //編譯器不推薦通過例項去呼叫靜態方法和屬性,因為這種呼叫方式容易造成混淆。 //實際上,在Java的規範中,Java對於類的方法和屬性採用了兩種完全不同的處理機制: //對於方法,使用過載機制實現了多型性;對於屬性,使用的是同名屬性隱藏機制。 //所謂的同名屬性隱藏機制是指:在具有父子關係的兩個類中, //子類中相同名字的屬性會使得從父類中繼承過來的同名屬性變得不可見, //不管型別是否一致,名稱一致的兩個屬性就是同名屬性。 //在子類中,無法簡單地通過屬性名稱來獲取父類中的屬性, //而是必須通過父類名稱加屬性名稱(super.變數名)的方法才可以訪問父類中的該屬性。 //一般而言,為了程式碼容易閱讀,極其不建議在父類和子類中使用同名屬性。 } }