super关键字作用:
- 主要存在于子类方法中,用于指向子类对象中父类对象。
- 访问父类的属性。
- 访问父类的函数。
- 访问父类的构造函数。
super相当于父类的构造方法,用来实例化父类对象,并且放在子类构造函数的第一行,当实例化子类对象时,先执行父类构造函数,实例化一个父类对象,再实例化一个子类对象。
Father:
package com.company;
public class Father {
private String Name;
public Father(){
System.out.println("I am Father");
}
public Father(int id){
System.out.println("I am Father and id ="+id);
}
}
Son:
package com.company;
public class Son extends Father{
private String Name;
public Son(){
//super();隐式语句
System.out.println("I am Son");
}
}
main:
package com.company;
public class Main {
public static void main(String[] args) {
Son son=new Son();
}
}
结果:的确是先执行父类构造函数再执行子类构造函数
其实就是说如果我们想实例化一个子类对象,必须先实例化一个父类对象。这样是合理的。比如有一个汽车类(Car),定义了汽车的基本属性,车身框架,车轮,引擎等属性;一个子类超级跑车(SuperCar)继承它,子类有导航系统,尾翼等属性。这是我们想实例化一个超级跑车类(SuperCar)对象,如果不先实例化一个汽车类(Car)对象,那么实例化的超级跑车连车轮,引擎,车身框架都没有,就只有尾翼,导航系统,很显然,这不叫一辆车。所以先实例化父类对象是为了让子类能够获得父类的属性和方法。
上面了解后,再来深入了解一下,本人亲自做过的某个公司的一道笔试题:
父类静态代码块,父类静态变量,父类非静态变量,父类构造函数,子类静态代码块,子类静态变量,子类非静态变量,子类构造函数的执行顺序?
直接代码测试:
Test:
package com.company;
public class Test {
public Test(String name){
System.out.println(name);
}
}
Father:
package com.company;
public class Father {
//父类非静态变量
public Test notstatic=new Test("我是父类非静态变量");
//父类静态变量
public static Test statictest=new Test("我是父类静态变量");
//父类静态代码块
static {
Test test1=new Test("我是父类静态代码块");
}
//父类构造函数
public Father(){
System.out.println("我是父类构造函数");
}
}
Son:
package com.company;
public class Son extends Father{
//子类非静态变量
public Test notstatictest=new Test("我是子类非静态变量");
//子类静态变量
public static Test statictest=new Test("我是子类静态变量");
//子类静态代码块
static {
Test test1=new Test("我是子类静态代码块");
}
//子类构造函数
public Son(){
System.out.println("我是子类构造函数");
}
}
main:
package com.company;
public class Main {
public static void main(String[] args) {
Son son=new Son();
}
}
结果:
从中可知:
- 先执行父类的静态变量和静态代码块,并且这两个的执行顺序没有先后之分,取决于代码的先后顺序。
- 然后执行子类的静态变量和静态代码块。也是没有先后之分。
- 执行父类的非静态变量
- 执行父类的构造函数。
- 执行子类的非静态变量。
- 执行子类的构造函数。