动态绑定 vs 静态绑定

动态绑定(又名后期绑定)

动态绑定是指编译器在编译阶段不知道要调用哪一个方法,直到运行时才能肯定。让咱们用个例子来解释。譬如咱们有一个叫做’SuperClass’的父类,还有一个继承它的子类’SubClass’。如今SuperClass引用也能够赋给SubClass类型的对象。若是SuperClass中有个someMethod()的方法,而子类也重写了这个方法,那么当调用SuperClass引用的这个方法的时候,编译器不知道该调用父类仍是子类的方法,由于编译器不知道对象究竟是什么类型,只有到运行时才知道这个引用指向什么对象。 git

1
2
3
4
5
6
7
8
...
SuperClass superClass1 =newSuperClass();
SuperClass superClass2 =newSubClass();
...
 
superClass1.someMethod();// SuperClass version is called
superClass2.someMethod();// SubClass version is called
....

咱们能够看到虽然对象引用superClass1和superClass2都是SuperClass类型的,可是在运行时它们分别指向SuperClass和SubClass类型的对象。 github

因此在编译阶段,编译器不清楚调用引用的someMethod()究竟是调用子类仍是父类的该方法。 spa

因此方法的动态绑定是基于实际的对象类型,而不是它们声明的对象引用类型。 htm

静态绑定(又名前期绑定)

若是编译器能够在编译阶段就完成绑定,就叫做静态绑定或前期绑定。基本上实例方法都在运行时绑定,全部的静态方法都在编译时绑定,因此静态方法是静态绑定的。由于静态方法是属于类的方法,能够经过类名来访问(咱们也应该使用类名来访问静态方法,而不是使用对象引用来访问),因此要访问它们就必须在编译阶段就使用编译类型信息来进行绑定。这也就解释了为何静态方法实际上不能被重写对象

更多阅读:能够重写静态方法吗? 继承

相似的,访问成员变量也是静态绑定的,由于Java不支持(其实是不鼓励)成员变量的多态行为。下面看个例子: ci

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
classSuperClass{
...
publicString someVariable ="Some Variable in SuperClass";
...
}
 
classSubClassextendsSuperClass{
...
publicString someVariable ="Some Variable in SubClass";
...
}
...
...
 
SuperClass superClass1 =newSuperClass();
SuperClass superClass2 =newSubClass();
 
System.out.println(superClass1.someVariable);
System.out.println(superClass2.someVariable);
...

输出: get

1
2
Some Variable in SuperClass
Some Variable in SuperClass

咱们能够发现成员变量由对象引用声明的类型决定,是由编译器在编译阶段就知道的信息,因此是静态绑定。另一个静态绑定的例子是私有的方法,由于它们不会被继承,编译器在编译阶段就完成私有方法的绑定了。 编译器

相关文章
相关标签/搜索