package a;public class A { /**
* @param args
*/
A(int x){
System.out.println("进入a的构造函数");
run();
}
public void run(){
System.out.println("运行a:run");
}}package a;public class B extends A { /**
* @param args
*/
B(int x, int y){
super(0);
}
public void run(){
System.out.println("运行b:run");
}}package a;public class C { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
int j = 0;
B object_B = new B(i,j);
}}第一次结果:调用父类构造函数
运行b.run
结束子类构造函数
------------------------
package a;public class A { /**
* @param args
*/
A(int x){
System.out.println("进入a的构造函数");
run();
}
public void run(){
System.out.println("运行a.run");
}}package a;public class B extends A { /**
* @param args
*/
B(int x, int y){
super(0);
}
private void run(){ // 此处为私有的与上边唯一的书写差别,当此处run方法被注释掉会报错
System.out.println("运行b.run");
}}package a;public class C { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
int j = 0;
B object_B = new B(i,j);
}}
第二次结果:调用父类构造函数
运行a.run
结束子类构造函数
----------------------
我想问一下上边和下边的运行上的差别,为什么在父类调用相同的名字时,第一次是调用子类的方法,第二次确是父类的,不要回答因为第二次是私有的不能被子类继承,这我知道,我是要原理上解释。我想知道当子类对象实例化时所调用的父类对象是以什么样的形式、顺序,我的理解是子类调用父类构造函数时所调用的方法应该是父类的,但结果却调用了子类重写的方法...这到底是为什么????
我想知道的是为什么调用重写的方法,我知道是方法重写,我不想知道这样的答案,我想知道他的实际运行原理。。比如:子类对象实例化时调用父类构造方法-〉执行父类构造方法的代码-〉System.out.println("进入a的构造函数");-〉run();关键现在到这了,程序走到这里现在是在父类的构造方法里,他怎么知道这个run方法被子类重写了???还有既然第一次能调用子类的run方法,那么我把父类的run注释掉应该还会调用子类的run,但我想错了,会报错,我是想知道这背后的东西。。
-----------------------------
* @param args
*/
A(int x){
System.out.println("进入a的构造函数");
run();
}
public void run(){
System.out.println("运行a:run");
}}package a;public class B extends A { /**
* @param args
*/
B(int x, int y){
super(0);
}
public void run(){
System.out.println("运行b:run");
}}package a;public class C { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
int j = 0;
B object_B = new B(i,j);
}}第一次结果:调用父类构造函数
运行b.run
结束子类构造函数
------------------------
package a;public class A { /**
* @param args
*/
A(int x){
System.out.println("进入a的构造函数");
run();
}
public void run(){
System.out.println("运行a.run");
}}package a;public class B extends A { /**
* @param args
*/
B(int x, int y){
super(0);
}
private void run(){ // 此处为私有的与上边唯一的书写差别,当此处run方法被注释掉会报错
System.out.println("运行b.run");
}}package a;public class C { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
int j = 0;
B object_B = new B(i,j);
}}
第二次结果:调用父类构造函数
运行a.run
结束子类构造函数
----------------------
我想问一下上边和下边的运行上的差别,为什么在父类调用相同的名字时,第一次是调用子类的方法,第二次确是父类的,不要回答因为第二次是私有的不能被子类继承,这我知道,我是要原理上解释。我想知道当子类对象实例化时所调用的父类对象是以什么样的形式、顺序,我的理解是子类调用父类构造函数时所调用的方法应该是父类的,但结果却调用了子类重写的方法...这到底是为什么????
我想知道的是为什么调用重写的方法,我知道是方法重写,我不想知道这样的答案,我想知道他的实际运行原理。。比如:子类对象实例化时调用父类构造方法-〉执行父类构造方法的代码-〉System.out.println("进入a的构造函数");-〉run();关键现在到这了,程序走到这里现在是在父类的构造方法里,他怎么知道这个run方法被子类重写了???还有既然第一次能调用子类的run方法,那么我把父类的run注释掉应该还会调用子类的run,但我想错了,会报错,我是想知道这背后的东西。。
-----------------------------
package a;public class A { /**
* @param args
*/
A(int x){
System.out.println("进入a的构造函数");
run();
}
public void run(){
System.out.println("运行a:run");
}}package a;public class B extends A { /**
* @param args
*/
B(int x, int y){
super(0);
}
public void run(){
System.out.println("运行b:run");
}}package a;public class C { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
int j = 0;
B object_B = new B(i,j);
}}第一次结果:调用父类构造函数
运行b.run
结束子类构造函数
------------------------
package a;public class A { /**
* @param args
*/
A(int x){
System.out.println("进入a的构造函数");
run();
}
private void run(){ // 此处为私有的与上边唯一的书写差别,当此处run方法被注释掉会报错
System.out.println("运行a.run");
}}package a;public class B extends A { /**
* @param args
*/
B(int x, int y){
super(0);
}
public void run(){
System.out.println("运行b.run");
}}package a;public class C { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
int j = 0;
B object_B = new B(i,j);
}}
第二次结果:调用父类构造函数
运行a.run
结束子类构造函数
----------------------
我想问一下上边和下边的运行上的差别,为什么在父类调用相同的名字时,第一次是调用子类的方法,第二次确是父类的,不要回答因为第二次是私有的不能被子类继承,这我知道,我是要原理上解释。我想知道当子类对象实例化时所调用的父类对象是以什么样的形式、顺序,我的理解是子类调用父类构造函数时所调用的方法应该是父类的,但结果却调用了子类重写的方法...这到底是为什么????
我想知道的是为什么调用重写的方法,我知道是方法重写,我不想知道这样的答案,我想知道他的实际运行原理。。比如:子类对象实例化时调用父类构造方法-〉执行父类构造方法的代码-〉System.out.println("进入a的构造函数");-〉run();关键现在到这了,程序走到这里现在是在父类的构造方法里,他怎么知道这个run方法被子类重写了???还有既然第一次能调用子类的run方法,那么我把父类的run注释掉应该还会调用子类的run,但我想错了,会报错,我是想知道这背后的东西。。
-----------------------------
可以看这个ppt
http://download.csdn.net/source/163042虽然做得不是非常好,但基本可以明白
private void run(){ // 此处为私有的与上边唯一的书写差别,当此处run方法被注释掉会报错如果在按第二次的代码那样,在父类中的run方法用private是不会报错的。这里报错是因为,父类的run方法是public,子类在重写父类的方法时,访问修饰要大于等于父类的,所以报错了。
这时,子类的run方法覆盖了父类的run方法,所以调用子类的方法。当父类的run方法是private,而子类的run方法是public时,
这两个方法就不是重写的关系。而是存在于两个类中不同的方法(如果用eclipse就会发现在子类的run方法前没有出现override的字样了)。
这时,调用的就会是父类的方法了。
likgui(游客)
hacklew1985()
momo8303()
感谢你们的回答虽然没有解决这个问题,你们能明白我的意识我很高兴,我还以为我这个想法我描述不明白呢!我自己写完了,我回过头来看都感到矛盾了。
至于>>yiyi2007()
我想你没有明白我的本意,或者你没有表达明白,你的回答我感觉,没有说到点子,你说的应该是继承上的基础理论。
对于你说的 “这里报错是因为,父类的run方法是public,子类在重写父类的方法时,访问修饰要大于等于父类的,所以报错了。”其实报错不子类,如果是你说的那样,报错的该是子类,而本题报错的是父类的构造方法里被调用的run();处。(eclipse报的错误是编译时的:The method run() is undifind for type A)
再有如果只是看成简单的重写问题,我大可不问了,你所说的run()方法是在子类中被调用的情况,现在是在父类中调用,那个调用的“句柄”到底是谁呢?是谁在父类构造器中扮演了主角?
我想第2种情况是编译器在编译时报错,那么就是说编译器认为,父类构造器掉的应该是自己的run()方法,但是被注释掉的话,编译器找不到run()方法了,那么也就是说编译器是不知道子类情况的,这说明问题是处在运行期间的,这也是我想知道的,究竟是如何运行的,这里我想到java晚邦定但是我还是希望高手来帮解决,度过这个思想上的障碍。