class Base{
int i=1;
public void amethod(){
System.out.println(“Base.amethod()”);
}
Base(){
amethod(); //调试时发现amethod()方法的实现代码是子类重写的代码?子类重写父类的方法,在父类指向子类时,父类的方法会变重写掉吗?
}
}
public class Descend extends Base{
int i=-1;
public static void main(String[] args){
Base b=new Descend(); //父类指向子类,那么在实例化时,应该是先去运行父类的构造方法,那么运行是应该是父类的amethod()方法呀,可是程序怎么是运行子类重写的amethod()???
System.out.println(b.i); // 调试时b是指向子类的对象,可是i却是父类的成员变量??
b.amethod(); 是父类的方法,却是子类的实现代码???
}
public void amethod(){
System.out.println(“Descend.amethod()”);
}
}
为什么运行出来的结果是
Descend.amethod()
1
Descend.amethod()
我想了解这个程序的运行机制,怎么会得到这种结果
颜色加深的地方是不理解的地方。
int i=1;
public void amethod(){
System.out.println(“Base.amethod()”);
}
Base(){
amethod(); //调试时发现amethod()方法的实现代码是子类重写的代码?子类重写父类的方法,在父类指向子类时,父类的方法会变重写掉吗?
}
}
public class Descend extends Base{
int i=-1;
public static void main(String[] args){
Base b=new Descend(); //父类指向子类,那么在实例化时,应该是先去运行父类的构造方法,那么运行是应该是父类的amethod()方法呀,可是程序怎么是运行子类重写的amethod()???
System.out.println(b.i); // 调试时b是指向子类的对象,可是i却是父类的成员变量??
b.amethod(); 是父类的方法,却是子类的实现代码???
}
public void amethod(){
System.out.println(“Descend.amethod()”);
}
}
为什么运行出来的结果是
Descend.amethod()
1
Descend.amethod()
我想了解这个程序的运行机制,怎么会得到这种结果
颜色加深的地方是不理解的地方。
Base b = new Descend();
创建Descend时,看Descend类有没有默认构造函数,没有的话调用父类的默认构造函数。
父类Base类中有amethod方法,这时,还是先查找子类复写父类的amethod方法没有。子类有amethod方法,就执行指令的amethodb.i子类的i=-1b.amethod()一样执行子类自身的方法。
如果子类重写了父类的amethod()方法,那么b.amethod()就会调用子类的amethod()方法,没有重写才会调用父类的amethod()方法
那么System.out.println(b.i); 怎么打印的是1,而不是-1呢?
Base b=new Descend();构造一个子类实例给父类。当运行时,java会检查到底是该实例子类还是父类。
如果是子类,会自动调用子类的方法。这就是运行时多态的体现。
至于b.i的问题。因为多态是针对方法级别的,而成员变量没有多态。
当运行时,如果父类引用是子类对象,就会调用子类的方法。这就是运行时多态的体现。
而数据成员b.i没有多态性,只能引用父类的成员
在你这段程序中Descend extends Base同时重写了amethod()方法;
所以当你Base b=new Descend();虽然父类指向子类,但在实例化时,程序运行的还是子类重写的amethod()方法;b.i的问题。因为多态是针对方法级别的,而成员变量没有多态。
Base b=new Descend(); 这句话叫做父类的引用指向子类的对象这是一个多态。
当你在main中写上
Base b=new CsdnDescend();
//System.out.println(b.i);
//b.amethod(); 1。把后面两句注释掉 同样会打印出:Descend.amethod();
这是因为你new的时候调用了父类的构造方法:Base();{amethod();}
而子类重写了amethod()这个方法所以会打印出:Descend.amethod();
2。b.i我认为b是父类的 引用 所以是调用父类声明的变量。只有方法可以重写
3。b.amethod() 同样的这里是调用父类的amtheod方法 但因为被子类重写了,所以调用子类的amethod方法。