Java之动态绑定

  • Post author:
  • Post category:java


所谓动态绑定,通俗的是指,对象在调用方法的时候能够自己判断该调用谁的方法。所以动态绑定一般发生在继承、方法重载时。

那么发生方法重载时,编译器如何确定调用的方法呢,例如,调用c.f(arg)时,首先需要将c声明为B类的对象,此时,如果在B类中,存在多个f方法,只是f的参数类型不同,调用f(int)或者f(String)时。编译器会注意列举B类中所有名为f的方法以及B类超类中的访问权限为public的名为f的方法。如果存在与c.f(arg)中arg类型相匹配的方法,那么就调用这个方法。由此,调用哪个方法隐式参数的实际类型。这个过程就是一个动态绑定的过程。

例:

package chapeter04;

class Test
{
	public Test() { }
	
	public void setName(String n)
	{
		this.name=n;
		System.out.println("在父类中");
	}
	
	public String getName()
	{
		return this.name;
	}
	
	private String name;
}

public class Sample4_12 extends Test
{
	public void setArea(String a)
	{
		this.area=a;
	}

	public String getArea()
	{
		return this.area;
	}
	
	public static void main(String[] args) 
	{
		// TODO Auto-generated method stub
		Sample4_12 child = new Sample4_12();
		
		Test test []=new Test[2];
		test[0]=child;
		test[0].setName("silence");
		test[1]=new Test();
	}
	
	private String area;

}

运行结果:

上面的例子执行过程如下:

  1. 查看test[0]声明类型,即Sample4_12 类,然后获得方法名 setName ,接着把PolymorphicTest 类中的所有名为setName的public方法列举出来。若没有名为setName的方法,则调用失败,否则转换到2。
  2. 根据调用方法的参数类型来对上一步列出来的所有方法进行匹配,直到找到一个匹配的转到3,否则匹配失败。
  3. 若test[0]所指向(refer to)的对象的类型为其一个子类,则需要查看子类有没有覆盖该方法,若有,则执行子类中的方法。

如果这个方法是private、static、final类型的,就不用进行动态绑定了,因为编译器可以很准确的知道要调用那个方法。且查询匹配方法时,是按照继承树逐级向上查找的,直到找到第一个匹配的方法为止。

但是由于Java中允许类型转换,所以寻找一个合适的方法是个复杂的过程,如果编译器没有找到合适的方法,或者发现类型转换后有多个方法与之匹配,则编译器会报错。



版权声明:本文为qq_41431457原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。