如題,直接帶入案例進行理解Java的動態綁定機制,不多說直接上代碼了。
package one;
public class JavaTest {
public static void main(String[] args) {
A obj = new B();
System.out.println(obj.sum());
System.out.println(obj.sum1());
}
}
class A {
public int i = 10;
public int sum() {
return getI() + 10;
}
public int sum1() {
return i+ 10;
}
public int getI() {
return i;
}
}
class B extends A{
public int i = 20;
public int sum() {
return getI() + 20;
}
public int sum1() {
return i + 10;
}
public int getI() {
return i;
}
}
輸出內容:
40
30
以上代碼不難理解,就是簡單的計算罷了。
但是我們改一下代碼,看看下面的內容:
package one;
public class JavaTest {
public static void main(String[] args) {
A obj = new B();
System.out.println(obj.sum());
System.out.println(obj.sum1());
}
}
class A {
public int i = 10;
public int sum() {
return getI() + 10;
}
public int sum1() {
return i+ 10;
}
public int getI() {
return i;
}
}
class B extends A{
public int i = 20;
// public int sum() {
// return getI() + 20;
// }
public int sum1() {
return i + 10;
}
public int getI() {
return i;
}
}
把classB裏的sum方法註釋了,返回的結果會是什麼呢?
輸出內容:
30
30
爲什麼第一個輸出內容變了呢?
這裏就涉及到了Java的動態綁定機制了,大概是這樣的:
- 如果調用的是方法,則jvm機會將該方法和對象的內存地址綁定
- 如果調用的是移歌屬性,則沒有動態綁定機制,在哪調用就返回對應值
所以,以上第一個輸出30大致是這樣的一個流程:因爲classB註釋了sum(),則首先調用的是classA的sum(),而後有調用getI(),這是調用方法,就與new classB()進行了動態綁定,則使用綁定classB裏的getI(),結果就是 20+10=30。
然後再次修改一下代碼:
package one;
public class JavaTest {
public static void main(String[] args) {
A obj = new B();
System.out.println(obj.sum());
System.out.println(obj.sum1());
}
}
class A {
public int i = 10;
public int sum() {
return getI() + 10;
}
public int sum1() {
return i+ 10;
}
public int getI() {
return i;
}
}
class B extends A{
public int i = 20;
// public int sum() {
// return getI() + 20;
// }
// public int sum1() {
// return i + 10;
// }
public int getI() {
return i;
}
}
輸出內容是:
30
20
那下面那個爲什麼會輸出20呢?
這是因爲把classB裏的sum1()註釋了,調用的是classA的sum1(),方法裏調用的i屬性,則不會進行動態綁定,直接調用classA的i,結果就是:10 + 10 = 20。