< 示例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
