class FatherObj{
int i = 1;
int x = getNum();
int y = getNum();
int getNum(){
System.out.println("FahterObj getNum()" + i++);
return i;
}
}class SonObj extends FatherObj{
int i = 1;
int x = getNum();
int y = getNum();
int getNum(){
System.out.println("SonObj getNum()" + i++);
return i;
}
public static void main(String args[]){
SonObj so = new SonObj();
}
}运行结果是:
SonObj getNum()0
SonObj getNum()1
SonObj getNum()1
SonObj getNum()2两点疑问:
1.为什么一开始是SonObj getNum()0,i的值为什么是0,不是1。
2.SonObj so = new SonObj();的时候,先是父类的变量初始化,它为什么执行子类的getNum()。
int i = 1;
int x = getNum();
int y = getNum();
int getNum(){
System.out.println("FahterObj getNum()" + i++);
return i;
}
}class SonObj extends FatherObj{
int i = 1;
int x = getNum();
int y = getNum();
int getNum(){
System.out.println("SonObj getNum()" + i++);
return i;
}
public static void main(String args[]){
SonObj so = new SonObj();
}
}运行结果是:
SonObj getNum()0
SonObj getNum()1
SonObj getNum()1
SonObj getNum()2两点疑问:
1.为什么一开始是SonObj getNum()0,i的值为什么是0,不是1。
2.SonObj so = new SonObj();的时候,先是父类的变量初始化,它为什么执行子类的getNum()。
SonObj getNum()1
SonObj getNum()2父类并没有执行子类的getNum();
然后子类中调用了两次getNum();
值增加如果你只是想测试i++,是先加还是后加,用如下程序:
public class SonObj {
static int i = 1;
static void getNum(){
System.out.println("SonObj getNum()" + i++);
System.out.println("SonObj getNum()" + ++i); } public static void main(String args[]){
SonObj so = new SonObj();
getNum();
} }结果
SonObj getNum()1
SonObj getNum()3
结论,i++是后加,++i是先加
运行到这的时候i++是先参与运算后++,结果就是0,但输出后i=1
2.SonObj so = new SonObj(); 你本身声明了一个子类对象,编译器自动寻找子类对象的方法
我的理解是在SonObj so = new SonObj(); 的时候,先是父类的变量初始化,按顺序执行int i = 1; int x = getNum(); int y = getNum(); 。此时i已经赋值为1了,但是getNum()打印出来的结果却是i为0。父类在执行getNum(),不是执行它本身的方法,却调用了子类的getNum()。这个要怎么解释?
这是jvm类家载的问题。
解释如下:
执行SonObj so = new SonObj(); 后会调用SonObj的默认构造方法SonObj(){super();},这时会实例化父类的成员变量,int i = 1;
当调用int x = getNum(); 时,jvm会查找子类是否有同名getNum()方法,如果没有,就执行父类的getNum()方法,因为之类有,所以执行了
子类的getNum()方法,而这时之类的i还没有实例化,所以i=0;
不属于类中的变量一但定义必须赋值
你可以这样试试就知道了
abstract class FatherObj{ //改成抽象类
int i = 1;
int x = getNum();
int y = getNum();
{Systen.out.println("FatherObj Create");}//打印一个确认信息
//int getNum(){
//System.out.println("FahterObj getNum()" + i++);
//return i;
//}
abstract int getNum(); //改成抽象方法
} class SonObj extends FatherObj{
int i = 1;
int x = getNum();
int y = getNum();
int getNum(){
System.out.println("SonObj getNum()" + i++);
return i;
} public static void main(String args[]){
SonObj so = new SonObj();
}
} 你就会发现父类初始化时会找到被子类覆盖过的对应的方法,因为你要生成的是子类的实例,所以在构造父类的时候,会以子类的同名方法来执行的,这样是为了保证子类的完整信息,否则你想想看,如果父类和子类的同名方法作了截然相反的事情,那不就冲突了吗?如果子类确实要调用父类的方法,应该由用户自己在子类的同名方法中通过super.xxx()来调用。
public class Test {
public static void main(String args[]){
SonObj so = new SonObj();
}
}class FatherObj{
int i = 1;
int x = getNum('X');
int y = getNum('Y');
int getNum(char c){
System.out.println("FahterObj getNum()" +c+ i++);
return i;
}
} class SonObj extends FatherObj{
int i = 1;
int x = getNum('x');
int y = getNum('y');
int getNum(char c){
System.out.println("SonObj getNum()" +c+ i++);
return i;
}
}
这样你能看的更清楚,结果是:
SonObj getNum()X0
SonObj getNum()Y1
SonObj getNum()x1
SonObj getNum()y2
看出了什么?那么这样呢:public class Test {
public static void main(String args[]){
SonObj so = new SonObj();
}
}class FatherObj{
int x = getNum('X');
int y = getNum('Y');
int i = 1;
int getNum(char c){
System.out.println("FahterObj getNum()" +c+ i++);
return i;
}
} class SonObj extends FatherObj{
int x = getNum('x');
int y = getNum('y');
int i = 1;
int getNum(char c){
System.out.println("SonObj getNum()" +c+ i++);
return i;
}
}
结果:
SonObj getNum()X0
SonObj getNum()Y1
SonObj getNum()x2
SonObj getNum()y3
先不说了,下班先,回去再说。