`

不要在构造器中调用可覆写的方法

 
阅读更多

        首先看一下下面的程序,猜猜会输出什么:

class Point{
  Point(){
     show();
  }
   void show(){
      System.out.println("Father.");
   }
}
class ColorPoint extends Point{
   void show(){
      System.out.println("Son.");
   }

  public static void main(String args[]){
       ColorPoint point=new ColorPoint();
   }

}

 由于,在子类的构造函数中会默认的调用父类的构造函数,但是父类的构造函数调用了被子类重载过得方法。这会导致直接调用子类覆盖后的方法。

所以输出结果:

Son.

 

     看懂了上面的代码,再分析分析下面的代码:

class Point{
	protected final int x,y;
	private final String name;
	Point(int x,int y){
		this.x=x;
		this.y=y;
		name=makeName();
	}
	protected String makeName(){
		return "["+x+","+y+"]";
	}
	public final String toString(){
		return name;
	}
}

public  class ColorPoint extends Point{
	
	private final String color;
	public ColorPoint(int x,int y,String color) {
		// TODO Auto-generated constructor stub
		super(x, y);
		this.color=color;
	}
	protected String makeName(){
		return super.makeName()+":"+color;
	}
	
	public static void main(String args[]){
		
		
		System.out.println(new ColorPoint(4, 2, "purple"));
	}
}

 当在父类中调用makeName()方法时,由于该方法已经被子类重写过了。所以直接调用的是子类的makeName()方法。由于此时导致color域还没有被赋值还是null,导致name已将变成了[4,2]:null。执行到

this.color=color;时虽然color域被赋值但是已经无法改变name域的值。所以输出了:

[4,2]:null

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics