前提知识提要
父类与子类
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承的特性
子类拥有父类非 private 的属性、方法。
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)
菜鸟教程
代码
class ParentClass {
static {
System.out.println("初始化父类静态代码块");
}
{
System.out.println("父类非静态代码块");
}
private String name;
public int value = 1;
public static int vara = 2;
/**
* 父类无参构造方法
*/
public ParentClass() {
System.out.println("父类无参构造方法");
value = 3;
vara = 4;
}
/**
* 父类有参构造方法
* @param name
*/
public ParentClass(String name) {
this.name = name;
System.out.println("父类有参构造方法:" + name);
}
/**
* 父类方法
* @param word
*/
public void parMethod(String word){
System.out.println("Method: 父类方法 + " + word);
}
}
class SubClass extends ParentClass {
static {
System.out.println("初始化子类静态代码块");
}
{
System.out.println("子类非静态代码块");
}
private String name;
public int subValue = 5;
public static int subVara = 6;
/**
* 子类无参构造方法
*/
public SubClass() {
System.out.println("子类无参构造方法");
subValue = 7;
subVara = 8;
}
/**
* 子类有参构造方法
* @param name
*/
public SubClass(String name) {
this.name = name;
System.out.println("子类有参构造方法:" + name);
}
@Override
public void parMethod(String word){
System.out.println("Method: 子类重写了父类方法 + " + word);
}
}
public class InitParentOrChildren {
public static void main(String[] args) {
//初始化子类 会先初始化父类
//初始化父类的时候,会先初始化父类的静态代码块
//然后再初始化子类的静态代码块
//接下来才是父类初始化--->子类初始化
// ParentClass par = new ParentClass("par");
// par.parMethod("spark");
SubClass sub1 = new SubClass();
SubClass sub = new SubClass("sub");
sub.parMethod("sub");
//sub.parMethod("test");
}
}
第一阶段结论
主方法只初始化了子类,调用的子类的有参构造方法;运行结果如下:
首先进行的是 父类的静态代码块初始化,然后再是子类的静态代码块。接下来就是父类和子类的初始化
得出结论
①子类构造器会隐式调用父类的无参构造方法
②子类初始化顺序 :
父类静态代码块–子类静态代码块–父类非静态代码块–父类无参构造方法–子类非静态代码块–子类无参构造方法
父类静态代码块–子类静态代码块–父类非静态代码块–父类无参构造方法–子类非静态代码块–子类有参构造方法
第二阶段结论
将main方法修改一下:
public static void main(String[] args) {
//初始化子类 会先初始化父类
//初始化父类的时候,会先初始化父类的静态代码块
//然后再初始化子类的静态代码块
//接下来才是父类初始化--->子类初始化
SubClass sub = new SubClass("subInit");
sub.parMethod("sub");
}
结果如下:
得出结论:
子类初始化会初始化父类
第三阶段结论
调整主方法里的代码:
public static void main(String[] args) {
SubClass sub = new SubClass("subInit");
sub.parMethod("sub");
ParentClass par = new ParentClass("parInit");
par.parMethod("par");
}
运行结果:
得出结论:
静态代码块只初始化一次