Java 中的初始化顺序的影响和“overloading”与“overwrite”
首先测试代码:
package com.gbd.test;
abstract class Base
{
Base()
{
System.out.print("base constructer and j = " + getj() + "\n");
}
void PrintJ()
{
System.out.print("PrintJ j is " + getj() + "\n");
}
int getj()
{
return 9;
}
void overloadingTest(double f)
{
System.out.print(" call float : f is " + f + "\n");
}
}
class Inher extends Base
{
protected int j = 5;
Inher()
{
System.out.print("Inher constructer and j = " + j + "\n");
}
int getj()
{
j = 10;
return j;
}
void overloadingTest(long l)
{
System.out.print(" call long : l is " + l + "\n");
}
}
public class inherConstructTest
{
Inher I = new Inher();
//Base I = new Inher();
I.PrintJ();
I.overloadingTest(0.32);
I.overloadingTest((long)1234567);
}
类继承的初始换顺序 首先来看下运行结果: base constructer and j = 10 Inher constructer and j = 5 PrintJ j is 10 call float : f is 0.32 call long : l is 1234567 这里有两个地方要注意下: 1. 继承的初始化顺序:
- 先基类的成员变量
- 基类的构造函数
- 超类的成员变量
- 超类的构造函数
所以,上面的new Inher()的时候,getJ() 已经调用的是超类的getJ()了。 此时将j = 10; 然而,在基类初始化完后,调用超类的成员变量初始化protected int j = 5; 又把j 赋值成5了, 所以在超类的构造函数时 J= 5; 修改测试: class Inher extends Base { protected int j; Inher() { System.out.print("Inher constructer and j = " + j + "\n"); } int getj() { j = 10; return j; } void overloadingTest(long l) { System.out.print(" call long : l is " + l + "\n"); } } 这里将超类的成员变量赋值去掉,结果为: base constructer and j = 10 Inher constructer and j = 10 PrintJ j is 10 call float : f is 0.32 call long : l is 1234567 可以看到,此时,j 的值未被超类变量赋值修改。 再次修改测试: class Inher extends Base { protected int j; Inher() { System.out.print("Inher constructer and j = " + j + "\n"); } int getj() { // j = 10; return j; } void overloadingTest(long l) { System.out.print(" call long : l is " + l + "\n"); } } 将j的赋值在超类函数中去掉,结果为: base constructer and j = 0 Inher constructer and j = 0 PrintJ j is 0 call float : f is 0.32 call long : l is 1234567 从这点上来看,引出了java代码编写的一个经验: 1.构造函数中调用非构造函数的方法需要特别注意,或者避免这种调用,这里,非构造函数在超类被继承时,很容易引起非预期的问题。 2. 成员变量如果不显示地赋值,那么系统会给与一个初始值。 3.如果成员变量显示地赋值,那么会在成员变量定义的类层次再次调用赋值的。 继承 与 “overloading”与“overwrite” void overloadingTest(double f) void overloadingTest(long l) public class inherConstructTest { public static void main(String arg[]) { // Inher I = new Inher(); Base I = new Inher(); I.PrintJ(); I.overloadingTest(0.32); I.overloadingTest((long)1234567); } } base constructer and j = 10 Inher constructer and j = 10 PrintJ j is 10 call float : f is 0.32 call float : f is 1234567.0 可以看出,此时 void overloadingTest(long l)
可以看出,如果成员变量没有显示赋值,类会给一个初始值
由上面 的测试继续看
被系统认为是“overloading”, 即使是在集成体系中(不在同一个类中)。
当修改代码:
时,运行结果:
未被识别出。
以上可以看出,“overloading”是可以在超类中扩展的,“overloading”被认为是新的接口,而不是“overwrite”。
当句柄指针声明为基类时,无法识别超类的"overloading"的接口。
所以“overloading”不要和“overwrite”混淆了,“overloading”不具有多态性。