多态:动态绑定
2017-10-09 本文已影响15人
susu2016
动态绑定
程序绑定的概念:
绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定.
静态绑定:
在程序执行前方法已经被绑定(也就是说在编译过程中就已经知道这个方法到底是哪个类中的方法),此时由编译器或其它连接程序实现。例如:C。
针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定
动态绑定:
后期绑定:在运行时根据具体对象的类型进行绑定。
若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。
动态绑定的过程:
- 虚拟机提取对象的实际类型的方法表;
- 虚拟机搜索方法签名;
- 调用方法。
1、下列代码输出是什么?为什么输出为 private f()?
//: polymorphism/PrivateOverride.java
//Trying to override a private method.
package polymorphism;
import static net.mindview.util.Print.*;
public class PrivateOverride {
private void f() {
print("private f()");
}
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
}
}
class Derived extends PrivateOverride {
public void f() {
print("public f()");
}
} /*
* Output: private f()
*/// :~
要点:
- private 默认为 final,不支持覆盖。
- 理解静态绑定和动态绑定。
- 编程规范:函数名避免与父类 private 方法相同,以免发生误解。
- 将 main 方法移到 PrivateOverride 类外会发现 private 方法无法访问。
2、下列代码输出是什么?为什么?
//: polymorphism/FieldAccess.java
// Direct field access is determined at compile time.
class Super {
public int field = 0;
public int getField() {
return field;
}
}
class Sub extends Super {
public int field = 1;
public int getField() {
return field;
}
public int getSuperField() {
return super.field;
}
}
public class FieldAccess {
public static void main(String[] args) {
Super sup = new Sub(); // Upcast
System.out.println("sup.field = " + sup.field + ", sup.getField() = " + sup.getField());
Sub sub = new Sub();
System.out.println("sub.field = " + sub.field + ", sub.getField() = " + sub.getField()
+ ", sub.getSuperField() = " + sub.getSuperField());
}
} /*
* Output: sup.field = 0, sup.getField() = 1 sub.field = 1, sub.getField() =
* 1, sub.getSuperField() = 0
*/// :~
要点:
- 类中的域是静态绑定的,父类引用直接访问域,会返回父类的值。
- 编程规范:域设置为 private,用 getter/setter 访问;避免父类和子类域名相同
3、下列代码输出是什么?为什么?
//: polymorphism/StaticPolymorphism.java
// Static methods are not polymorphic.
class StaticSuper {
public static String staticGet() {
1 Thanks to Randy Nichols for asking this question.
return "Base staticGet()";
}
public String dynamicGet() {
return "Base dynamicGet()";
}
}
class StaticSub extends StaticSuper {
public static String staticGet() {
return "Derived staticGet()";
}
public String dynamicGet() {
return "Derived dynamicGet()";
}
}
public class StaticPolymorphism {
public static void main(String[] args) {
StaticSuper sup = new StaticSub(); // Upcast
System.out.println(sup.staticGet());
System.out.println(sup.dynamicGet());
}
} /*
* Output: Base staticGet() Derived dynamicGet()
*/// :~
要点:
- static 方法是静态绑定的