谈论“多态”需要首先涉及“前期绑定”和“后期绑定”。
一、前期绑定 1.1、概念 在编译期,完成前期绑定。
1.1.1、“实例对象访问成员”形式的前期绑定 实例对象访问成员,参见如下示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package chapter8;public class A { static int b = 20 ; int a = 10 ; static int g () { return 40 ; } int f () { return 30 ; } public static void main (String[] args) { A a = new A(); System.out.println(a.a); System.out.println(a.b); System.out.println(a.f()); System.out.println(a.g()); } }
前期绑定描述:
确定实例对象对应的声明Java类(注意不是实例对象对应的实际Java类 ),基于该声明Java类的实际定义进行访问成员的绑定
当该声明Java类的实际定义中含有0个匹配的候选项时,前期绑定失败,编译报错;当该声明Java类的实际定义中含有大于0个匹配的候选项时,依据一定的策略进行选取绑定(笔者不在这里探讨详细的策略),比如“原生成员优先级高于继承成员”,如果由于“违反约束条件”等原因导致不能顺利选取绑定则前期绑定失败,编译报错,否则前期绑定成功
1.1.2、“直接通过类访问成员”形式的前期绑定 直接通过类访问成员,参见如下示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package chapter8;public class A { static int b = 20 ; int a = 10 ; static int g () { return 40 ; } int f () { return 30 ; } public static void main (String[] args) { System.out.println(A.b); System.out.println(A.g()); } }
前期绑定描述:
基于所使用Java类的实际定义进行访问成员的绑定
当该使用Java类的实际定义中含有0个匹配的候选项时,前期绑定失败,编译报错;当该使用Java类的实际定义中含有大于0个匹配的候选项时,依据一定的策略进行选取绑定(笔者不在这里探讨详细的策略),比如“原生成员优先级高于继承成员”,如果由于“违反约束条件”等原因导致不能顺利选取绑定则前期绑定失败,编译报错,否则前期绑定成功
1.2、几个例子 1.2.1、例子1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package chapter8;public class Polymorphic1 extends A1 { int a = 20 ; public static void main (String[] args) { A1 a1 = new Polymorphic1(); System.out.println(a1.a); } } class A1 { int a = 10 ; }
1.2.2、例子2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package chapter8;public class Polymorphic2 extends A3 { public static void main (String[] args) { Polymorphic2 polymorphic2 = new Polymorphic2(); System.out.println(polymorphic2.a); } } class A2 { int a = 10 ; } class A3 extends A2 { int a = 30 ; }
1.2.3、例子3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package chapter8;interface A5 { int a = 40 ; } public class Polymorphic3 extends A4 implements A5 { public static void main (String[] args) { Polymorphic3 polymorphic3 = new Polymorphic3(); System.out.println(polymorphic3.a); } } class A4 { int a = 10 ; }
1.2.4、例子4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package chapter8;public class Polymorphic9 extends A15 { public static void main (String[] args) { System.out.println(Polymorphic9.a); } } class A15 { static int a = 10 ; }
二、后期绑定 2.1、概念 在运行期,完成后期绑定。后期绑定只针对“一般方法”成员,因此只有“实例对象访问成员”形式的后期绑定。 后期绑定描述:
需要特别注意的是 ,在后期绑定之前已经完成了前期绑定,如果后期绑定未作重新绑定,则使用前期绑定的结果
确定实例对象对应的实际Java类,基于该实际Java类的实际定义查找覆盖 欲访问一般方法的方法
当该实际Java类的实际定义中含有0个匹配的候选项时,后期绑定未作重新绑定,使用前期绑定的结果,运行不报错 ;当该实际Java类的实际定义中含有大于0个匹配的候选项时,依据一定的策略进行选取绑定(笔者不在这里探讨详细的策略),比如“必须是非虚方法”,“原生一般方法优先级高于继承一般方法”等,如果由于“违反约束条件”等原因导致不能顺利选取绑定则后期绑定失败,运行报错,否则后期绑定成功,后期绑定作重新绑定
2.2、几个例子 2.2.1、例子1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package chapter8;public class Polymorphic4 extends A6 { public static void main (String[] args) { Polymorphic4 polymorphic4 = new Polymorphic4(); System.out.println(polymorphic4.f()); } int f () { return 20 ; } } abstract class A6 { abstract int f () ; }
2.2.2、例子2 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 package chapter8;public class Polymorphic5 extends A8 { public static void main (String[] args) { A7 a7 = new Polymorphic5(); System.out.println(a7.f()); } int f () { return 30 ; } } class A7 { int f () { return 10 ; } } class A8 extends A7 { int f () { return 20 ; } }
2.2.3、例子3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package chapter8;interface A9 { int f () ; } public class Polymorphic6 extends A10 { public static void main (String[] args) { Polymorphic6 polymorphic6 = new Polymorphic6(); System.out.println(polymorphic6.f()); } } class A10 implements A9 { public int f () { return 30 ; } }
2.2.4、例子4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package chapter8;interface A12 { int f () ; } public class Polymorphic7 extends A11 implements A12 { public static void main (String[] args) { Polymorphic7 polymorphic7 = new Polymorphic7(); System.out.println(polymorphic7.f()); } } class A11 { public int f () { return 30 ; } }
2.2.5、例子5 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 package chapter8;public class Polymorphic8 { public static void main (String[] args) { Polymorphic8 polymorphic8 = new A13(); System.out.println(polymorphic8.f()); A13 a13 = new A13(); System.out.println(a13.f()); } private int f () { return 40 ; } } class A13 extends Polymorphic8 { int f () { return 30 ; } }
综上,多态的本质为:访问“一般方法”成员,后期绑定可以改变前期绑定的结果。