< 示例1>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21



<練習>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

這個地方就是多態的一個陷阱;
多態是對方法而言的,不是對變量;
s1 a = new s2();這里生成的對象是s1類的實例,但是是由s2類構造的;
java中對變量的選擇是靜態的,對方法的選擇是動態的,是在運行時決定的。(static除外)
運行時實際上調用的是實例的方法,即s1的方法;但對于繼承(多態的一種方式),方法的定位是在動態執行時選擇的,選擇實際構造者,因此就出現了本題的現象了。
另外:多態是對方法而言的,不是對變量;這樣說有些不嚴密,方法應該有個修飾,就是除了final修飾的方法外,java中對函數的調用都是后期綁定,所謂的后期綁定就是動態選擇
摘自 崔毅解答csdn疑問時給出的分析
注意以下的方法都被修飾了final
< 示例2>以下哪里會出錯?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

op2.f(); 處出錯!
<示例3>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18


1

2

3

分析
多態:
Java 中的函數,除了聲明外 final 的外,都是后期綁定。
所謂綁定是建立“函數調用”和“函數本體”的關聯。、
所謂的后期綁定是指執行時根據對象類別而進行
多態僅僅對函數而言,不對變量而言;
變量的訪問依賴于編譯期引用指向的類型;
方法的訪問依賴于執行期對象的類型;
向上轉型后,調用某個函數,若 derived class overriding 了該函數,則會調用該 derived class 中的函數,否則會調用 base class 中的函數。
向上轉型后,只能調用 base class 中被 derived class overriding 的函數,不能調用 derived class 中 extend 函數。
即向上轉型后,只能調用 base class 中的方法,不能調用 derived class 中的擴展方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18


1

2

3

4

5


1

2

3

4

5

6

--------取于 崔毅 之《java編程指南》《java編程思想》學習筆記l
以下是強化和復習:
1 多態只針對非final方法;
不針對變量、final方法
2方法[非final]是運行時對應對象
變量、fianl是編譯期間對應對象
3多態只能調用父類中有的方法(向上擴展后)
不能調用父類中沒有的方法;
不能調用子類中擴展父類[not overridding]方法
4多態定義:指的是使用同一個實現接口,以實現不同的對象實例
多態好處:多態讓程序依賴接口或者抽象類,而不是具體類
p.s
1
class Base {
2
int x = 2 ;
3
String s="s1";
4
int method() {
5
return x;
6
}
7
public String method2(){
8
return s;
9
}
10
}
11
class SubClass extends Base {
12
int x = 3 ;
13
String s="s2";
14
int method() {
15
return x;
16
}
17
public String method2(){
18
return s;
19
}
20
}
21
public class t4 {
22
23
public static void main(String[] args) {
24
Base b = new SubClass ();
25
System.out.println(b.x);
26
System.out.println(b.method());
27
System.out.println("-----用new SubClass會如何?------");
28
System.out.println(new SubClass().x); //相當于 SubClass a=new SubClass(); 然后a.x
29
System.out.println(new SubClass().method());//相當于a.method();
30
System.out.println(new SubClass().s);
31
System.out.println(new SubClass().method2());
32
System.out.println("-----直接new SubClass的test結束------");
33
System.out.println(b.s);
34
System.out.println(b.method2());
35
36
37
}
38
39
}
40
1
2
2
3
3
-----用new SubClass會如何?------
4
3
5
3
6
s2
7
s2
8
-----直接new SubClass的test結束------
9
s1
10
s2
11
這說明直接寫new son();//相當于 son son=new son();

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


2

3

4

5

6

7

8

9

10

11
