class Base {
int a = 10;
public void show() {
System.out.println(a);
}
}
class Ext extends Base {
int a = 200;
public void show(String s) {
System.out.println(s);
}
}
public class MyMain {
public static void main(String[] argv) {
Ext obj = new Ext();
obj.show(); // 輸出 10
obj.show("OK"); // 輸出 OK
}
}
成員變數(欄位)不支援多型,它們在編譯期靜態解析;方法在執行期動態分派。子類別定義同名欄位時,會隱藏父類別的同名欄位,而非覆寫。
class S1 {
public String s = "S1";
public String getS() { return s; }
}
class S2 extends S1 {
public String s = "S2";
public String getS() { return s; }
}
public class Shadow {
public static void main(String[] args) {
S1 s1 = new S1();
S2 s2 = new S2();
System.out.println(s1.s); // S1
System.out.println(s1.getS()); // S1
System.out.println(s2.s); // S2
System.out.println(s2.getS()); // S2
s1 = s2; // 父類別參考指向子類別物件
System.out.println(s1.s); // S1 —— 編譯期看型別 S1
System.out.println(s1.getS()); // S2 —— 執行期看實際物件 S2
}
}
s1.s 存取的是 S1 宣告的欄位,因為變數型別是 S1,編譯期綁定s1.getS() 呼叫的是 S2 覆寫的方法,執行期動態分派,存取 S2 的 sgetter/setter 方法封裝欄位private,提供公開的存取方法