//Circle1.java
package song;
public class Circle1 extends Point1 {
   private double radius;  
   public Circle1(){
      //��ʽ�ص��ó���Point1���޲ι��캯��
      System.out.println( "Circle1 no-argument constructor: " + this );
   } 
   public Circle1( int xValue, int yValue, double radiusValue ){
      super( xValue, yValue );    //��ʽ�ص��ó���Ĵ�}�����Ĺ��캯��
      setRadius( radiusValue );
      System.out.println( "Circle1 constructor: " + this );
   } 
   protected void finalize(){
      System.out.println( "Circle1 finalizer: " + this );
      super.finalize();  //���ó����finalize���� 
   }
   public void setRadius( double radiusValue ){
      radius = ( radiusValue < 0.0 ? 0.0 : radiusValue );
   } 
   public double getRadius(){
      return radius;
   } 
   public double getDiameter(){
      return 2 * getRadius();
   } 
   public double getCircumference(){
      return Math.PI * getDiameter();
   } 
   public double getArea(){
      return Math.PI * getRadius() * getRadius();
   } 
   public String toString(){
      return "Center = " + super.toString() + "; Radius = " + getRadius();
   } 
}

解决方案 »

  1.   

    //Point1.java
    public class Point1 {
       private int x;  
       private int y;  
       public Point1(){ //Point1类的无参构造函数
          System.out.println( "Point1 no-argument constructor: " + this );
       } 
       public Point1( int xValue, int yValue ){   //Point1类的带有参数的构造函数
          System.out.println( "Point1 constructor: " + this );
       } 
       protected void finalize(){ //Point1类的finalize方法
          System.out.println( "Point1 finalizer: " + this );
       } 
       public void setX( int xValue ){
          x = xValue;  
       } 
       public int getX(){
          return x;
       } 
       public void setY( int yValue ){
          y = yValue;  
       } 
       public int getY(){
          return y;
       } 
       public String toString(){
          return "[" + getX() + ", " + getY() + "]";
       } 
    }
      

  2.   

    //ConstructorFinalizerTest.java
    public class ConstructorFinalizerTest {
       public static void main( String args[] ){
          Point1 point;
          Circle1 circle1, circle2;
          point = new Point1( 11, 22 ); //创建Point1类的对象将调用该类的构造函数
          System.out.println();
          //创建Circle1类的对象将调用该类的构造函数
          //在调用Circle1类的构造函数前,首先要调用超类的构造函数
          circle1 = new Circle1( 72, 29, 4.5 );
          System.out.println();
          //创建Circle1类的对象将调用该类的构造函数
          //在调用Circle1类的构造函数前,首先要调用超类的构造函数
          circle2 = new Circle1( 5, 7, 10.67 );
          point = null;     //将point的引用设置为null 
          circle1 = null;   //将circle1的引用设置为null
          circle2 = null;   //将circle2的引用设置为null
          System.out.println();
          //显式调用垃圾收集程序将调用设为null的对象的finalize方法
          System.gc();  
       } 
    }
      

  3.   

    运行结果:
    Point1 constructor: [100, 100]Point1 constructor: Center = [100, 100]; Radius = 0.0   
    Circle1 constructor: Center = [100, 100]; Radius = 4.5Point1 constructor: Center = [100, 100]; Radius = 0.0   ????
    Circle1 constructor: Center = [100, 100]; Radius = 10.67Point1 finalizer: [100, 100]
    Circle1 finalizer: Center = [100, 100]; Radius = 4.5
    Point1 finalizer: Center = [100, 100]; Radius = 4.5     ????
    Circle1 finalizer: Center = [100, 100]; Radius = 10.67
    Point1 finalizer: Center = [100, 100]; Radius = 10.67有????号的地方请高手解释一下原因,谢谢!
      

  4.   

    其中的this是什么意思?高手能给解释一下吗?
      

  5.   

    第一个circle2 = new Circle1( 5, 7, 10.67 );是这一步然后实质性 public Circle1( int xValue, int yValue, double radiusValue ){
          super( xValue, yValue );   在调用public Point1( int xValue, int yValue ){   //Point1类的带有参数的构造函数
          System.out.println( "Point1 constructor: " + this );
    所以使这个结果
    第二个是
    执行 circle1 = null;  调用
    protected void finalize(){
          System.out.println( "Circle1 finalizer: " + this );
          super.finalize();  //&#65533;&#65533;&#65533;ó&#65533;&#65533;&#65533;&#65533;finalize&#65533;&#65533;&#65533;&#65533; 
       }
    在调用
      protected void finalize(){ //Point1类的finalize方法
          System.out.println( "Point1 finalizer: " + this );
       } 
    okle码
      

  6.   

    eoe2005(吃掉大象的蚂蚁):谢谢你的回答,你好像只写出了调用的顺序,我是想知道为什么
    Point1 constructor: Center = [100, 100]; Radius = 0.0 中的Radius = 0.0,是怎么得出来的,Point1 finalizer: Center = [100, 100]; Radius = 4.5 中的Radius = 4.5 是怎么得出来得,谢谢!
      

  7.   

    楼主的代码太乱了,看得我好累啊。虽然分析你的程序,好像和结果有点对不上号,但我似乎知道你要问的是什么了。这个例子在《Thinking in JAVA》有一个十分类似的,但比你的这个要精练得多。其实这里关键是要搞清楚两件事:1. 把一个对象和一个字符串相加时,会自动调用这个对象和toString()函数。2. 父类中的toString()函数是被子类覆盖了的,这样就构成了多态。也就是说,当从父类中调用toString()的时候,实际上是调用子类的toString()。记住这两点就可以来分析程序了:你问的第一个地方,是从Circle类中调用父类Point类的构造函数,在构造函数中引用了this,而this代表的是对象自身,根据上面的第1条,这时会自动调用父类对象的toString(),根据第2条,这时实际上调用的呢,是子类的toString()。所以子类的toString()被调用,对应的语句是return "Center = " + super.toString() + "; Radius = " + getRadius();但这时,子类并未初始化,现在要调用它的函数了,它就不得不草草地初始化一下了,用《Thinking in JAVA》中的话说就是“部分初始化(partially formed)”,这将导致一些所需的字段,如这里的radius,被赋默认值(对于double类型是0.0)。所以getRadius()方法返回了0.0。在finalize()方法中,仍然是因为toString()方法被动态绑定(即多态地调用)而出现所输出的结果,只是这时radius字段已经被赋值了,所以它的确切值被显示了出来。
      

  8.   

    对不起,纠正一处:“但这时,子类并未初始化……”应该是“但这时,子类对象并未初始化……”,子类其实已经初始化了。这个刻意而为之的例子告诉我们:应该尽量避免在构造函数中调用被子类覆盖了的方法,这将导致很难发现的bug(difficult-to-find bugs)。
      

  9.   

    Dan1980(有了Eclipse,再也不用记事本编程了,Eclipse真好!-) 谢谢你的精彩回答!
    我还有一处不明白,根据你说的“根据第2条,这时实际上调用的呢,是子类的toString()。所以子类的toString()被调用,对应的语句是return "Center = " + super.toString() + "; Radius = " + getRadius();”而这句话中又调用的父类的tostring()方法,而调用父类的tostring方法实际上是调用子类的tostring方法,这样不是要形成循环调用了吗??!!请解答困惑,谢谢!
      

  10.   

    当明确地用super关键字来调用父类的方法时,当然父类的实际方法就被调用,而不再是多态地调用了。