Topic: 关于this 和 super的!

  Print this page

1.关于this 和 super的! Copy to clipboard
Posted by: fossil
Posted on: 2005-09-15 18:03

class Point{
  protected int x,y;
  public Point(int a,int b){
    x=a;
    y=b;
    System.out.println("Point constructor:"+this.toString());
  }
  public String toString(){
    return"["+x+","+y+"]";
    }
  }  
    class Circle extends Point{
      protected double radius;
      public Circle(double r,int a,int b){
        super(a,b);
        radius=r;
        System.out.println("Circle constructor:"+this.toString());
      }
      public String toString(){
        return "Center="+super.toString()+"Radius="+radius;
      }
    }
    public class Test{
      public static void main(String[] args){
        Circle circle1,circle2;
        circle1=new Circle(4.5,72,29);
        circle2=new Circle(10.0,5,5);
      }
}

为什么this.toString() 方法是调用的是子类的方法!那么this.toString()是什么意思?
高手解答!

2.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: fossil
Posted on: 2005-09-15 18:05

运行结果:
Point constructor:Center=[72,29]Radius=0.0
Circle constructor:Center=[72,29]Radius=4.5
Point constructor:Center=[5,5]Radius=0.0
Circle constructor:Center=[5,5]Radius=10.0

3.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: 科大梦之队
Posted on: 2005-09-15 19:59

toString()方法是用来返回对象的字符串表示,可以用于显示一个对象.
关键词this可以用来表示这个对象本身,也就是在普通方法中,this表示调用这个方法的对象;在构造方法中,this表示新创建的对象.
通过this不仅可以引用该类中定义的域和方法,还可以引用该类的父类中定义的域和方法;
而有时为了明确地指明父类的域和方法,就要用关键字super.

4.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: 科大梦之队
Posted on: 2005-09-15 20:05

我感到迷惑不解的是:
一,程序中this.toString()全部将"this."去掉,运行结果不变.
二, "System.out.println("Point constructor:"+this.toString());"输出结果既引用了 "return"["+x+","+y+"]";"又引用了"return "Center="+super.toString()+"Radius="+radius;"
我也想知道,希望哪位高手解答一下,我也感激不尽!

5.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: fossil
Posted on: 2005-09-15 21:36

关键是System.out.println("Point constructor:"+this.toString());
这句和
System.out.println("Circle constructor:"+this.toString());
有什么区别!

当中2个this的涵义!


Please consider the use of the editing feature instead of making another post.

6.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: why
Posted on: 2005-09-15 23:08

"this" is always of type Circle, unless you cast it as a Point.

7.Re:关于this 和 super的! [Re: why] Copy to clipboard
Posted by: ranchgirl
Posted on: 2005-09-16 10:52

why wrote:
"this" is always of type Circle, unless you cast it as a Point.


I partially disagree. This is a partially incorrect answer. Smile
1) You only build 2 Circle object instances, even Point constructor is called. Only 2 objects are build, not four.

2) "unless you cast it as a Point"??? No, cast does not change dynamic binding!!! To illustrate this concepts, I have changed the code a little, and declare 2 Points instead. Please read, compile, and run the code to see the result / dynamic binding does not change. The run result screen text is also attached.

3) In the code, I print out this instead of this.toString(), the result does not change. When printing an object reference, the toString() is called. If you don't provide one, the default toString() in Object will be called.

~~~~~~~~~~~~~~
Q. What is Java key word this?
A: this is a keyword used in Java/C++ code to refer the current instance object itself.

~~~~~~~~~~~~~~

~~~~~~~~~~~~~~
Q. Another interesting example to illustrate the concepts. It might be controversial too.
A:
An Asian boy was born.

A boy was born.
An Asian was born.
A human was born.
A creature was born.

All above statements are true. How many creatures were born during the process?

Only one!

This very Asian boy inherited all its base class features as a boy, an Asian, as a human, and as a creature.

If you happen to be a Darwinist, do not believe creation, if you are doing research on the development of human embryo, you might even understand how those constructors were called during the process. Wink
~~~~~~~~~~~~~~


class Point {
protected int x,y;
public Point(int a,int b) {
x=a;
y=b;
System.out.println("1: " + this); // print this
}
public String toString() {
return "[" + x + "," + y + "]";
}
}
class Circle extends Point {
protected double radius;
public Circle(double r,int a,int b) {
super(a,b);
radius=r;
System.out.println("2: " + this); // print this
}
public String toString(){
return "Center = " + super.toString() + ", Radius = " + radius;
}
}
public class Test {
public static void main(String[] args) {
Point p1,p2;
// from Circle to Point, we don't need to cast here
p1 = new Circle(4.5,72,29);
p2 = new Circle(10.0,5,5);
}
}



C:\>javac Test.java

C:\>java -cp . Test
1: Center = [72,29], Radius = 0.0
2: Center = [72,29], Radius = 4.5
1: Center = [5,5], Radius = 0.0
2: Center = [5,5], Radius = 10.0

8.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: fossil
Posted on: 2005-09-16 17:12

3q

9.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: ranchgirl
Posted on: 2005-09-16 20:04

To fossil

I've modified the above answer to make it clearer, also added test code with result

Read, please!

Thanks!

10.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: fossil
Posted on: 2005-09-16 21:33

3q

11.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: why
Posted on: 2005-09-17 05:58

sorry, my mistake...

12.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: ranchgirl
Posted on: 2005-09-17 11:17

Thanks why for adding points on my account, thanks! Smile

13.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: intothehit
Posted on: 2005-09-26 10:51

But why Radius = 0.0 is displayed? The parent's constructor does not include radius, who can tell me?

14.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: ranchgirl
Posted on: 2005-09-26 11:24

The toString() is called before the radius is initialized!!!

15.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: oliver456
Posted on: 2005-09-27 18:23

to gongshi
gongshi said
The toString() is called before the radius is initialized!!!


我有点不同意你的观点,初始化这个词用的比较模糊。
对于本题,有两次调用toString() :
第一次调用是在调用Point的构造函数时用的,此时域 radius 只被设定为默认初始值(double类型的默认初始值为0.0,boolean类型的默认初始值为false 等等 );
第二次调用是在调用Circle 的构造函数时用的,此时域 radius 已被初始化,即它的值为9.0。
下面有修改后的程序和运行结果
Smile

16.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: oliver456
Posted on: 2005-09-27 18:37

class Point {
protected int x,y;
public Point(int a,int b)
{ x=a;
y=b;
System.out.println("1: " + this); // print this
}
public String toString()
{ return "[" + x + "," + y + "]";
}
}
class Circle extends Point
{ protected double radius=9.0;
public Circle(int a,int b)
{ super(a,b); System.out.println("2: " + this); // print this
}

public Circle(double r,int a,int b)
{ super(a,b); radius=r; System.out.println("2: " + this); // print this
}
public String toString()
{ return "Center = " + super.toString() + ", Radius = " + radius; }
}
public class Test
{ public static void main(String[] args)
{ Point p1,p11; // from Circle to Point, we don't need to cast here
p11=new Circle(72,29);
p1 = new Circle(4.5,72,29);

}
}
下面是运行结果

C:\>javac Test.java
C:\>java -cp . Test
1: Center = [72,29], Radius = 0.0
2: Center = [72,29], Radius = 9.0
1: Center = [72,29], Radius = 0.0
2: Center = [72,29], Radius = 4.5


17.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: oliver456
Posted on: 2005-09-27 19:14

总结

[color=navy] 上面的运行结果了调用构造函数的顺序;
在创造对象的时候,将会对所用的域分配内存,包括从超类继承来的,并且这些域都会设置为相应类型的默认值,让后调用构造函数
每个 构造函数的执行有三个阶段:
1)调用超类的 构造 函数;
2)利用初始化语句对域进行初始化;
3)执行构造函数。


[/navy]

18.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: oliver456
Posted on: 2005-09-27 19:16

总结


上面的运行结果了调用构造函数的顺序;
在创造对象的时候,将会对所用的域分配内存,包括从超类继承来的,并且这些域都会设置为相应类型的默认值,让后调用构造函数

每个 构造函数的执行有三个阶段:
1)调用超类的 构造 函数;
2)利用初始化语句对域进行初始化;
3)执行构造函数。



19.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: sle315
Posted on: 2005-09-27 22:52

刚学JAVA,什么都不懂,琢磨了一晚上,才大体有个概念:
这个问题要谈到构造方法,和super,this的引用,具体不多说,只说程序运行的顺序,
1,分配成员变量,并初始化.Circle(double r,int a,int b)默认初试化
2,寻找构造方法,并按构造方法赋值.super(a,b);调用父类构造方法,super的用法之一是调用被父类,如上指定参数就是指定调用父类的哪一个构造方法.
3,如果碰到this调用,则调用相应的重载构造方法,父类中碰到this:System.out.println("Point constructor:"+this.toString());调用被重载的构造方法,调用完毕回到当前构造方法,执行语句.

20.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: 科大梦之队
Posted on: 2005-09-28 18:32

我一直在研究这个题,以上各位的解释我都不能认同,这应该是个
方法的覆盖问题.

class Point{
protected int x,y;
public Point(int a,int b){
x=a;
y=b;
System.out.println("Point constructor:"+this.toString());
}
public String toString(){//父类的方法
return"["+x+","+y+"]";
}
}
class Circle extends Point{
protected double radius;
public Circle(double r,int a,int b){
super(a,b);
radius=r;
System.out.println("Circle constructor:"+this.toString());
}
public String toString(){// 子类重新定义与父类同名的方法,实现对父类方法的覆盖!
return "Center="+super.toString()+"Radius="+radius;
}
}
public class Test{
public static void main(String[] args){
Circle circle1,circle2;
circle1=new Circle(4.5,72,29);
circle2=new Circle(10.0,5,5);
}
}
所以两次调用的都是子类的方法,不过父类缺少一个域,就采用了默认值!

21.最后的解决! [Re: fossil] Copy to clipboard
Posted by: 科大梦之队
Posted on: 2005-09-28 20:55

在构造子类的一个对象时,子类构造方法会调用父类的构造方法,而如果父类的构造方法中如果调用了对象的其他方法,如果所调用的方法被子类所覆盖的话,它可能实际上调用的是子类的方法,这是由动态绑定(虚方法调用)所决定的.

22.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: mastersky
Posted on: 2005-09-28 23:10

Super调用的是父类的构造函数,执行父类构造函数里面的语句,但是除此之外的所有函数应该以子类中的函数版本为准。
即执行Point中System.out.println("Point constructor:"+this.toString());的时候
this.toString()方法用的是子类中的方法。那个this是指circle1或者circle2这个具体的实例,而不是指Point这个类。

23.Re:关于this 和 super的! [Re: 科大梦之队] Copy to clipboard
Posted by: fossil
Posted on: 2005-10-01 10:19

科大梦之队 wrote:
我一直在研究这个题,以上各位的解释我都不能认同,这应该是个
方法的覆盖问题.

class Point{
protected int x,y;
public Point(int a,int b){
x=a;
y=b;
System.out.println("Point constructor:"+this.toString());
}
public String toString(){//父类的方法
return"["+x+","+y+"]";
}
}
class Circle extends Point{
protected double radius;
public Circle(double r,int a,int b){
super(a,b);
radius=r;
System.out.println("Circle constructor:"+this.toString());
}
public String toString(){// 子类重新定义与父类同名的方法,实现对父类方法的覆盖!
return "Center="+super.toString()+"Radius="+radius;
}
}
public class Test{
public static void main(String[] args){
Circle circle1,circle2;
circle1=new Circle(4.5,72,29);
circle2=new Circle(10.0,5,5);
}
}
所以两次调用的都是子类的方法,不过父类缺少一个域,就采用了默认值!

我比较同意这个观点!

24.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: awardwy
Posted on: 2005-10-03 21:46

科大梦之队 I agree with you;
this is a method override question.

25.Re:关于this 和 super的! [Re: fossil] Copy to clipboard
Posted by: 流水野云
Posted on: 2005-10-18 14:09

这确实是一个方法覆盖的问题,在实际应用中该程序是不容易读的,我个人认为改成如下形式较维护和易读:
class Point{
protected int x,y;
public Point(int a,int b){
x=a;
y=b;
System.out.println("Point constructor:"+toString());
}
public String iString(){
return"["+x+","+y+"]";
}
}
class Circle extends Point{
protected double radius;
public Circle(double r,int a,int b){
super(a,b);
radius=r;
System.out.println("Circle constructor:"+toString());
}
public String toString(){
return "Center="+super.iString()+"Radius="+radius;
}
}
public class Test{
public static void main(String[] args)
{
Circle circle1,circle2;
circle1=new Circle(4.5,72,29);
circle2=new Circle(10.0,5,5);
}
}


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923