高手来解释一下这个程序

Dragon_sxw 2008-07-19 02:42:37
public class Teacher extends Person {
public Teacher() {
super();
}

public Teacher(int a) {
System.out.println(a);
}

public void func() {
System.out.print("2, ");
}

public static void main(String[] args) {
Teacher t1 = new Teacher();
Teacher t2 = new Teacher(3);
}
}

class Person {
public Person() {
func();
}

public void func() {
System.out.println("1, ");
}
}


为什么运行结果是 2, 2, 3

请高人指点~
...全文
90 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
妄旺 2008-07-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 ZangXT 的回复:]
引用 9 楼 billgacsli 的回复:
我倒是晕了,莫非方法的动态绑定是在对象被创建之前?

示例中,创建Teacher实例时,会先调用其父类Person的构造函数,而此时,Teacher对象还没创建出来,怎么能在构造函数中就实现多态呢?

这样思考问题的话构造方法中就不能调用别的方法了。
[/Quote]
倒也是哦,晕了~~~
ZangXT 2008-07-19
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 billgacsli 的回复:]
我倒是晕了,莫非方法的动态绑定是在对象被创建之前?

示例中,创建Teacher实例时,会先调用其父类Person的构造函数,而此时,Teacher对象还没创建出来,怎么能在构造函数中就实现多态呢?
[/Quote]
这样思考问题的话构造方法中就不能调用别的方法了。
Sou2012 2008-07-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ZangXT 的回复:]
你把例子改一下,让父类中没有缺省的构造方法,子类中也没有显示调用父类构造方法的语句,看看编译效果就明白了。
[/Quote]
妄旺 2008-07-19
  • 打赏
  • 举报
回复
我倒是晕了,莫非方法的动态绑定是在对象被创建之前?

示例中,创建Teacher实例时,会先调用其父类Person的构造函数,而此时,Teacher对象还没创建出来,怎么能在构造函数中就实现多态呢?
Dragon_sxw 2008-07-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ZangXT 的回复:]
你把例子改一下,让父类中没有缺省的构造方法,子类中也没有显示调用父类构造方法的语句,看看编译效果就明白了。
[/Quote]

呵呵,按你的说法试了试, 即使去掉Teacher中的super()方法, 程序结果相同, super方法隐式的被调用了。。。

学习了, 3ks
ZangXT 2008-07-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 shmilycharlene 的回复:]
在这个程序中Teacher中的super()似乎是没有用的.不使用这个.其结果是一样的....
那么我的解释是当Teacher继承Person的时候.Teacher的无参构造中应该是
public Teacher(){
func();//隐含的调用.
}
然后在子类中进行了覆盖.所以在实例化的时候就调用的是子类的方法.当然就是2了.

关键字super可被用来引用该类中的超类。它被用来引用超类的成员变量或方法。通常当覆盖一个方法时,实际目的不是要更换现有的行为,而是要在某…
[/Quote]
不管子类的构造方法是什么样子的,如果你不显示调用,编译器肯定会帮你添加super()的,所以如果父类没有默认构造方法,程序会出现编译错误。通过this引用其他构造方法的方式除外,呵呵
shmilycharlene 2008-07-19
  • 打赏
  • 举报
回复
在这个程序中Teacher中的super()似乎是没有用的.不使用这个.其结果是一样的....
那么我的解释是当Teacher继承Person的时候.Teacher的无参构造中应该是
public Teacher(){
func();//隐含的调用.
}
然后在子类中进行了覆盖.所以在实例化的时候就调用的是子类的方法.当然就是2了.

关键字super可被用来引用该类中的超类。它被用来引用超类的成员变量或方法。通常当覆盖一个方法时,实际目的不是要更换现有的行为,而是要在某种程度上扩展该行为。


期待高手解答,和纠正.
爱摸鱼de老邪 2008-07-19
  • 打赏
  • 举报
回复
楼上动作真快!!!
ZangXT 2008-07-19
  • 打赏
  • 举报
回复

package test;

public class Teacher extends Person {
public Teacher() {
super();
}

public Teacher(int a) {
System.out.println(a);
}

public void func() {
System.out.print("2, ");
}

public static void main(String[] args) {
Teacher t1 = new Teacher();
Teacher t2 = new Teacher(3);
}
}

class Person {
public Person() {
func();
func2();
}

public void func() {
System.out.println("1, ");
}

public void func2() {
System.out.println("test");
}
}

通过在父类中添加下面的方法,你可以测试一下执行顺序,子类没有覆盖父类的改方法,所以调用的是父类的方法。
public void func2() {
System.out.println("test");
}
ZangXT 2008-07-19
  • 打赏
  • 举报
回复
你把例子改一下,让父类中没有缺省的构造方法,子类中也没有显示调用父类构造方法的语句,看看编译效果就明白了。
ZangXT 2008-07-19
  • 打赏
  • 举报
回复
Teacher t1 = new Teacher();
这里创建Teacher类的对象,首先调用Test类的构造方法,这个过程首先调用父类的构造方法,父类构造方法中调用func(),因为子类覆盖了这个方法,所以实际调用的是子类中的func方法。所以输出2,

Teacher t2 = new Teacher(3);
同样,首先调用Test的构造方法
public Teacher(int a) {
System.out.println(a);
}
虽然你没有显示调用super(),编译器会自动添加并调用父类的构造方法,同样,因为多态,调用子类的func(),输出2,然后调用
System.out.println(a);
输出3
所以结果是2,2,3

关键是两点:
1.多态
2.父类构造方法的执行。如果你不显示添加,编译器也会添加。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧