继承中的super关键字以及代码块执行顺序

继承中的super关键字以及代码块执行顺序

1.父类和子类

​ 子类继承父类,那么子类就可以拥有父类中所有的公共的(public)属性及方法,当多个类中描述的属性及行为是相同的或者大部分是相同的,此时就可以考虑是用继承,以简化代码。在Java的普通类中是不允许出现多继承的(会出现调用不明确的问题),但是可以有继承体系。

​ Java 的继承通过 extends 关键字来实现,extends 关键字使用代码演示如下:

//父类
public class ParentClass{
     
    ...
}
//子类继承父类
public class SubClass extends ParentClass{
        
    ...
}

​ 此时SubClass类就有了ParentClass类中所有的公共的(public)属性及方法。

2.super关键字

​ 关键字 super 指代父类,可以用于调用父类中的普通方法和构造方法。只要存在继承关系,调用子类中的构造器时,构造方法中就会默认去执行super(),super()默认不写的,另外,如果要显示的写出来,那必须在第一行。在子类中的方法之所以可以互相调用是因为都默认持有了一个this对象,存在继承关系时,子类中在调用父类中的属性及方法时都默认持有了super关键字。

super关键字的作用:

  1. 调用父类构造方法
  2. 调用父类方法

子类构造器中的super关键字

/**
 * 父类--人 
 */
public class Person {
     
	//年龄
	 int age ;
	//性别
	String sex;
	//名字
	String name;
	//父类构造器
	public Person() {
     
		System.out.println("父类构造器Person()执行");
	}
	//人的吃饭功能
	public void eat() {
     
		System.out.println("吃饭");
	}
	//人的社交功能
	public void social() {
     
		System.out.println("社交");
	}
}
/**
 * 子类--学生
 */
public class Student {
     
	//学号
	int number;
	//子类构造器
	public Student(){
     
        //super();//super()可以不写的,默认存在。如果要显示的写出来,必须在第一行。
		System.out.println("子类构造器Student()执行");
	}
	//子类的功能
	public void study() {
     
		System.out.println("在学校学习");
	}	
}

​ 创建一个子类对象

public class test {
     
	public static void main(String[] args) {
     
		Student studen = new Student();		
	}
}
//运行结果为
/*    
父类构造器Person()执行
子类构造器Student()执行
*/

​ 子类构造器内默认包含super();这行代码,因此在这行语句执行前先执行了父类构造器。

3.父类与子类中代码块执行的优先级

当涉及到继承时,按照如下顺序执行:

1.执行父类的静态代码块,并初始化父类静态成员变量

2.执行子类的静态代码块,并初始化子类静态成员变量

3.执行父类的构造代码块,执行父类的构造函数,并初始化父类普通成员变量

4.执行子类的构造代码块, 执行子类的构造函数,并初始化子类普通成员变量

/**
 *子类 
 */
class A extends B{
     
    //子类构造代码块
	{
     
		System.out.println("子类构造代码块");
	}
    //子类静态构造代码块
    static{
     
        System.out.println("子类静态构造代码块");
    }
 	//子类构造器
	public A() {
     
		//super();//在子类构造器内会存在一个默认的super(),且只能存在于第一个语句
		System.out.println("子类构造器");
	}	
}

/**
 *父类 
 */
class B{
     
    //父类构造代码块
	{
     
		System.out.println("父类构造代码块");
	}
    //父类静态构造代码块
    static{
     
        System.out.println("父类静态构造代码块");
    }
 	//父类构造器
	public B() {
     
		System.out.println("父类构造器");
	}
}
//创建子类对象
public class CodeBlock{
     
	public static void main(String[] args) {
     
		A a = new A();
	}
}
//输出结果顺序如下
/*
父类静态构造代码块
子类静态构造代码块
父类构造代码块
父类构造器
子类构造代码块
子类构造器
*/

具体分析:

​ 静态构造代码块在加载类时运行,由于继承关系,编译时先加载父类,再加载子类,所以父类静态构造代码块优先输出,之后是子类静态代码块。在语句创建对象时,由于继承关系,优先运行了默认存在于子类构造器中的,父类先开始初始化,构造代码块的执行次序优先于类构造器,因此父类构造代码块、父类构造器依次初始化输出。最后子类开始初始化,子类构造代码块、构造器依次初始化输出。

你可能感兴趣的:(继承中的super关键字以及代码块执行顺序)