对java多态的理解

<!-- @page { margin: 0.79in } P { margin-bottom: 0.08in } -->

java中的多态的理解

Thinking in java中的一个例子:

构造器中的多态:

public class Glyph {
	int radius = 5;
	  void draw() {
		  System.out.println("Glyph.draw()"); 
		  System.out.println(this.getClass());
	  }
	  
	 static void showInfo() {
		  System.out.println("Glyph showInfo");
	  }
	  
	  Glyph() {
	    System.out.println("Glyph() before draw()\n\tradius="+radius);
	    draw();
	    showInfo();
	    System.out.println("Glyph() after draw()");
	  }
}
 
class RoundGlyph extends Glyph {
	
	  private int radius = 10;
	  
	  RoundGlyph(int r) {
		System.out.println("RoundGlyph.radius="+radius);
	    radius = r;
	    System.out.println("RoundGlyph.RoundGlyph()\n\tthis.radius=" + 
	    		this.radius+"\tsuper.radius="+super.radius);
	  }
	  
	  void draw() {
	    System.out.println("RoundGlyph.draw(), radius = " + radius);
	    System.out.println(this.getClass());
	    System.out.println(super.getClass());
	  }
	  
	  static void showInfo() {
		  System.out.println("RoundGlyph showInfo");
	  }
}
 
public class PolyConstructors {

	public static void main(String[] args) {
		new RoundGlyph(15);
		System.out.print("\n\n\n");
		new Glyph();
	}

}
 

 

运行输出:

Glyph() before draw()

radius=5

RoundGlyph.draw(), radius = 0

class RoundGlyph

class RoundGlyph

Glyph showInfo

Glyph() after draw()

RoundGlyph.radius=10

RoundGlyph.RoundGlyph()

this.radius=15 super.radius=5




Glyph() before draw()

radius=5

Glyph.draw()

class Glyph

Glyph() after draw()

 

 

对输出结果的解释:

复杂对象调用构造器要遵照下面的顺序 :

1. 调用基类构造器。这个步骤会不断地反复递归下去 , 首先是构造这种层次结构的根 ,

然后是下一层导出类 , 等等。直到最低层的导出类。

2. 按声明顺序调用成员的初始状态设置模块。

3. 调用导出类构造器的主体。

初始化的实际过程是 :

1. 在其他任何事物发生之前 , 将分配给对象的存储空间初始化成二进制的零。

2. 如前所述的那样 , 调用基类构造器。此时 , 调用被重载的 draw() 方法 ( 是的 ,

在调用 RoundGlyph 构造器之前调用的 ), 由于步骤 (1) 的缘故 , 我们此时会发

radius 的值为 0

3. 按照声明的顺序调用成员的初始化代码。

4. 调用导出类的构造器主体。

 

在本例中为:

分配内存并初始化为二进制的零。调用 Glyph 中的成员初始状态设置模块即 radius=5; 接着调用 Glyph 类的构造器 Glyph():

System.out .println("Glyph() before draw()\n\tradius=" +radius );

输出:

Glyph() before draw()

radius=5

draw();

输出:

RoundGlyph.draw(), radius = 0 // ( 此处为什么是 0, 而不是 5)

class RoundGlyph

class RoundGlyph

showInfo();

输出:

Glyph showInfo

System. out .println( "Glyph() after draw()" );

输出:

Glyph() after draw()

这后调用 RoundGlyph 中的成员初始状态设置模块即 radius=10;( 由于在基类及导出类类都定义了 radius ,因此当在 RoundGlyph 类中定义的 radius 会覆盖在 Glyph 中定义的 radius, 两个 radius 都存在但不同。然后就是调用导出类中的构造器 RoundGlyph():

输出:

RoundGlyph.RoundGlyph()

this.radius=15 super.radius=5

 

java 中方法的动态绑定:

非静态方法调用时有一个隐式的参数 this, 表示当前对象。本例中的 Glyph 中的 draw(), 实际上为 draw(Glyph this), RoundGlyph 中的 draw() draw(RoundGlyph this). 静态方法是在编译时绑定的,非表态方法是运行时动态绑定的。由于每个非静态方法都有一个 this 参数, 虚拟机由此可以确定是函数是属于哪一个类的,并该类的函数表中去查找此函数, 如果能找到该函数,否则到基类的函数表是去查找,依此类推。

你可能感兴趣的:(java,虚拟机)