Java 中方法調用的綁定機制取決於引用變量類型與實際對象類型的關係,理解這三條規則至關重要:
public class Person {
public String name;
public void getInfo() { System.out.println("父類"); }
}
public class Student extends Person {
@Override
public void getInfo() {
super.getInfo();
System.out.println("子類");
}
public static void main(String[] args) {
Person s = new Student();
Person t = new Person();
s = t; // s 現在引用 Person 對象
s.getInfo(); // 輸出:父類
}
}
解析:雖然 s 初始指向 Student,但賦值 s = t 後實際引用變為 Person 對象,調用 getInfo() 時根據實際對象綁定至父類方法。
public class Person {
public static void getInfo() { System.out.println("父類"); }
}
public class Student extends Person {
public static void getInfo() { System.out.println("子類"); }
public static void main(String[] args) {
Person s = new Student();
s.getInfo(); // 輸出:父類(等價於 Person.getInfo())
}
}
關鍵點:靜態方法屬於類而非實例。s.getInfo() 編譯期即綁定至 Person.getInfo(),與實際對象無關。這不是重寫,而是方法隱藏。
public class Person {
public String name = "father";
}
public class Student extends Person {
public String name = "son";
public static void main(String[] args) {
Person s = new Student();
Person t = new Person();
s = t;
System.out.println(s.name); // 輸出:father
}
}
結論:成員變量(含 static 變量)訪問時綁定聲明類型 Person 的 name,與實際對象無關。即使改為 static String name 結果相同。
Student s = new Student(); // 可調用 Student 特有方法 Person t = new Student(); // 僅能調用 Person 定義的方法
當子類擁有父類沒有的特有方法(如 goSchool())時,只有 s 可調用,t 編譯報錯。這體現了引用類型決定可見成員範圍的原則。
staticJava 綁定機制本質:非靜態方法看對象,靜態方法與變量看引用類型。這是面向對象多態性的核心體現,也是開發中常見 Bug 來源。掌握這三條規則,能避免 90% 的繼承相關邏輯錯誤。