一直以为自己多态学的不错,今天拿到一题目,还是没理解。程序如下:public class Father { public void test(){
System.out.println("Father.test()");
}
public Father(){
System.out.println("Father.Father()");
test();
}
}public class Son extends Father { public Son(){
System.out.println("Son.Son()");
test();
}
public void test(){
System.out.println("Son.test()");
}
public static void main(String[] args) {
Son son = new Son();
}
}我在子类里new了一个Son,而且类型也是Son,并没有用到多态啊,为什么在父类的构造器里的test方法调用的是子类的test方法呢?
System.out.println("Father.test()");
}
public Father(){
System.out.println("Father.Father()");
test();
}
}public class Son extends Father { public Son(){
System.out.println("Son.Son()");
test();
}
public void test(){
System.out.println("Son.test()");
}
public static void main(String[] args) {
Son son = new Son();
}
}我在子类里new了一个Son,而且类型也是Son,并没有用到多态啊,为什么在父类的构造器里的test方法调用的是子类的test方法呢?
楼主【milooxu】截止到2008-07-28 21:14:48的历史汇总数据(不包括此帖):
发帖的总数量:2 发帖的总分数:20 每贴平均分数:10
回帖的总数量:3 得分贴总数量:1 回帖的得分率:33%
结贴的总数量:2 结贴的总分数:20
无满意结贴数:1 无满意结贴分:20
未结的帖子数:0 未结的总分数:0
结贴的百分比:100.00% 结分的百分比:100.00%
无满意结贴率:50.00 % 无满意结分率:100.00%
敬礼!
Son.Son()
Son.test()
不知道对不?请指点。为什么在父类的构造器里的test方法调用的是子类的test方法呢?
回答:因为父类和子类里面都有一个test方法,子类把父类里的test()覆盖掉了。所以,当我们创建一个子类的对象时,调用的是子类的test()。
Father.Father()
Son.test()
Son.Son()
Son.test()
应该是这样的:这是构造方法调用的问题!
当你调用子类的构造方法时候,要先调用父类的构造方法,然后再调用子类的。
那第二个为什么输出的是Son.test()呢,因为在子类中覆盖了父类中的方法。如果子类中的test改成test2输出就是Father.test()了。
应该是这样的把,有点忘记了。
当你调用Sun()的构造函数public Son()时,
相当于是这样的:
public Son(){
super.Father();
System.out.println("Son.Son()");
test();
}
没有爸爸,哪来的孩子啊??对不对
这样的话
你的程序等价于先执行了
System.out.println("Father.Father()");
test();
然后执行了
System.out.println("Son.Son()");
test(); 所以答案是:
Father.Father()
Son.test()
Son.Son()
Son.test()
明白了吗??不明白的话加我QQ 64832013
大家共同进步~~~
Father.test()
Son.Son()
Son.test() 刚开始还以为是这个答案,呵呵
如果我Father f = new Son(); 的话这是多态我理解,但我现在是Son son = new Son(); 这根本就没多态,只是一个继承关系而已。
如果在一个构造器的内部,同时调用在构造的那个对象的某个动态绑定方法,就要用到那个方法的被覆盖后的定义。
构造器内部有多态方法时怎么调用构造器呢?
1):在其他任何事情发生之前,将分配给对象的储存空间将初始化成二进制的零。
2):调用被覆盖的方法。
3):按照申明的顺序调用成员的初始化。
4):调用子类的构造器主体。
举个书上的例子:abstract class Glyph {
abstract void draw();
Glyph() {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}class RoundGlyph extends Glyph {
int radius = 1;
RoundGlyph(int r) {
radius = r;
System.out.println(
"RoundGlyph.RoundGlyph(), radius = "
+ radius);
}
void draw() {
System.out.println(
"RoundGlyph.draw(), radius = " + radius);
}
}public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
输出
Glyph() before draw();
RoundGlyph.draw(),radius=0;//radius=0应为步骤1的初始化
Glyph() after draw();
RoundGlyph.RoundGlyph() radius=5;
应该ok了把……
其实像这种构造一点都不好。
编写构造器的时候有一条准则:尽可能用简单的方法使对象进入正常状态,如果可以得话,避免调用其他方法。在构造器唯一能能够安全调用的那些方法是基类中的final方法。
其实上
A xx=new A();你也可以理解成xx是对对象new A()的引用...
输出结果是: Father.Father()
Son.test()
Son.Son()
Son.test()原因:当你调用Son()构造方法创建son对象时,因为Son是Father的子类,所以要先创建父类对象,
就像八楼说的,没有爸爸哪来孩子。
这样的话就要先执行Father()构造方法,所以先输出Father.Father(),
然后本来是接着执行Father类里面的test()方法的,可是因为子类重写了父类里面的test()方法,相当于覆盖了它,
所以要执行子类的test()方法,输出Son.test(),
再下去就是执行子类的构造函数了,再依次输出Son.Son(),Son.test()
我还是没有理解为什么父类构造器里面的test()方法实际调用的是子类的test()方法。。
static
Father.Father()
Father.test() ---------调用的是父类的test()方法
Son.Son()
Father.test()---------调用的是父类的test()方法