在java中多態分為兩種編譯時多態(重載)和運行時多態(重寫),編譯時多態又叫前綁定,運行時多態又叫后綁定。
下面用一個例子說明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
public class OverloadAndOverwrite { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.print( "a1.print(a1): " ); a1.print(a1); //輸出A and A System.out.print( "a1.print(b): " ); a1.print(b); //輸出A and A:原因是因為A中不存在參數為B的方法,因此會調用參數為A的方法,因為B是繼承自A的 System.out.print( "a1.print(c): " ); a1.print(c); //輸出A and A:原因是因為A中不存在參數為C的方法,因此會調用參數為A的方法,因為C是繼承自B的,B是繼承自A的 System.out.print( "a1.print(d): " ); a1.print(d); //輸出A and D:原因是因為A中存在參數為D的方法,因此會調用參數為D的方法 System.out.print( "a2.print(b): " ); a2.print(b); //輸出B and A:原因在于首先入口是A,首先查看A中是否有參數為B的print方法,發現沒有那就尋找有沒有參數為A的方法,因為B是繼承自A的,發現存在這樣的方法,那么再次查看B中有沒有重寫這個方法,發現有重新,直接調用B中這個重寫的方法 System.out.print( "a2.print(c): " ); a2.print(c); //輸出B and A:原因在于首先入口是A,首先查看A中是否有參數為C的print方法,發現沒有那就尋找有沒有參數為B的方法,因為C是繼承自B的,發現也不存在這樣的方法,那就尋找存在參數為A的print方法,因為B繼承自A,發現存在這樣的方法,那么再次查看B中有沒有重寫這個方法,發現有重新,直接調用B中這個重寫的方法 System.out.print( "a2.print(d): " ); a2.print(d); //輸出 A and D:原因在于入口是A,查看A中存在參數為D的方法,再次查看B中沒有重寫這個方法,因此輸出A中這個方法的結果即可; System.out.print( "a2.print(a2): " ); a2.print(a2); //輸出B and A;原因在于a2的類型是A,因此會調用A里面參數為A的print方法,但是a2右邊new的是B,所以因為B中有參數為A的方法,因此采用的是B里面的這個方法 System.out.print( "b.print(b): " ); System.out.print( "b.print(c): " ); b.print(c); //輸出B and B;原因:入口是B,因此查看B中存不存在參數為C的print函數,發現不存在,則查看存不存在參數為B的print函數,發現存在,并且C中并沒有重寫該方法,則直接輸出;有一點需要注意的是還需要查看一下A中是否存在參數為C的print方法,因為B繼承自A,有的話會及成果來這個方法,這樣的話輸出的結果將變為A and C System.out.print( "b.print(d): " ); b.print(d); //輸出A and D;原因:入口是B,雖然B中不存在參數為D的print函數,但是B繼承自A,A中是存在參數為D的print函數的,因此輸出的是A中參數為D的結果; } } class A { public void print(A a) { System.out.println( "A and A" ); } public void print(D d) { System.out.println( "A and D" ); } // public void print(C c) // { // System.out.println("A and C"); // } } class B extends A { public void print(B b) { System.out.println( "B and B" ); } public void print(A a) { System.out.println( "B and A" ); } } class C extends B{} class D extends C{} |
在此需要說明的是:
對于 A a2 = new B( );
如果單獨打印出a2的話,打印結果是B@(hash碼),而不是A@(hash碼),但這并不能說明a2的類型是B類型的,因為當我們在上面程序中調用a2.print(a2);的時候輸出的結果是B and A而不是A and A(如果假設a2是B類型的話,就應該調用A類中參數為B的print方法,因為不存在這樣的方法,那么退而求其次調用參數為A的方法就應該輸出A and A了,因為B是A的子類)。
以上就是對重寫和重載的實例代碼分析,希望對Java學習的同學有幫助。