首先是网上关于super用法的简介:
基础知识
1、super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句)
2、super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时)
如:super.变量名 super.成员函数据名(实参)
3、如果父类中的成员变量和方法被定义为private类型,那么子类永远无法访问它们,如果试图采用super.var的形式去访问父类的private类型的var变量,就会导致编译错误。(如果是protected则可以)
我遇到的问题:
某程序在其构造函数中调用了super(),但却没反应,代码和原因都写在注释里了(该代码同时还测试子类在实例化时构造函数以及成员变量的实例化顺序,因此写了很多辅助类如Test2、Test3):
[code]
class Test3{
Test3(){System.out.println("in the Test3()");}
}
class Test2{
Test2(){System.out.println("in the Test2()");}
void a(){}
}
class Test {
private Test2 t2 = new Test2();
protected Test2 t22 = new Test2();
Test() {
System.out.println("in the Test()");
}
Test(int i) {
System.out.println("in the Test(int i)");
}
}
public class TestConstructor extends Test{
private Test2 t2 = new Test2();
protected Test2 t22 = new Test2();
/* 这里的t2、t22覆盖了父类中的t2、t22,所以要引用父类的中变量就要用super.xxx */
private Test3 t3 = new Test3();
TestConstructor(){
//super();
/* super()是用来调用父类默认的构造子,但子类在实例化时会自动调用父类的默认构造子,不需要显示调用,所以一般不用super(),而用super(参数)来调用带参构造子,因为带参构造子是不会在子类实例化是被调用的,必须显示调用 */
//super(1);
/* 这里如果写上这句话,则在实例化TestConstructor时将不再调用父类的默认构造子Test(),而是调用带参构造子Test(int) */
//super.t2.a();
/* 这样写编译器会报错,因为t2是父类(Test)中的private成员 */
super.t22.a();
/* 这样写就没问题,因为t22在父类中是protected的 */
System.out.println("in the TestConstructor()");
}
public static void main(String[] args) {
Test
supertest = new Test(),
subtest = new TestConstructor();
}
}
[/code]
该程序输出结果是:
[code]
in the Test2() //实例化Test类时先实例化其成员变量t2
in the Test2() //实例化Test类时先实例化其成员变量t22,注意t2和t22按声明顺序实例化
in the Test() //调用Test类的构造子
in the Test2()
in the Test2()
in the Test() /*上面三句是前三句的重复,因为TestConstructor是Test的子类,在实例化子类时会先将父类的所有初始化工作完成,也就是先执行前三句,接下来的四句是子类自己的初始化工作*/
in the Test2() //实例化自己的成员变量t2
in the Test2() //实例化自己的成员变量t22
in the Test3() //实例化自己的成员变量t3
in the TestConstructor() //调用自己的构造子
[/code]