Java只支持单继承,不支持多继承。
super是一个关键字,代表父类的存储空间标识。(可以理解为父亲的引用)
super和this的用法相似。
this代表对象的引用(谁调用就代表谁);
super代表当前子类对父类的引用。
在子类方法中访问一个变量
子类局部范围查找
子类成员范围查找
父类成员范围查找
如果都没有就报错(不考虑父亲的父亲)
子类成员范围查找
父类成员范围查找
如果都没有就报错(不考虑父亲的父亲)
子类中所有构造方法默认都会访问父类无参构造方法。
因为子类会继承父类中的数据,可能还会使用父类中的数据,因此,子类初始化前,会先初始化父类。
可以通过super关键字显式调用父类有参构造,或父类添加无参构造
子类中出现与父类一模一样的方法时(除了权限修饰符,权限修饰符大于等于不包括private,返回值类型,方法名和参数列表相同),会出现覆盖操作,称为重写
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,既沿袭了父类的功能,又定义了子类特有的内容。
私有方法不能被重写(父类私有成员子类不能继承)
子类方法权限修饰符大于等于父类(public>默认>私有)
方法的重写用在子类方法与父类方法一模一样时,除权限修饰符,返回值类型,方法名和参数列表都是相同的。
重载用在同一个类中各方法方法名相同,参数列表不同(与返回值类型没有关系)的情况。
父类静态代码块→子类静态代码块→父类构造代码块→父类构造方法→子类构造代码块→子类构造方法
class Fu {public int num = 10;public Fu() {System.out.println("fu");}
}class Zi extends Fu {public int num = 20;public Zi() {System.out.println("zi");}public void show() {int num = 30;System.out.println(num); //30System.out.println(this.num); //20System.out.println(super.num); //10}
}
class ExtendsTest {public static void main(String[] args) {Zi z = new Zi();z.show();}
}
fuzi302010
知识点:子类的所有构造方法执行前默认先执行父类的无参构造方法
知识点:访问成员变量的原则:就近原则(子类局部>子类成员>父类成员)。
this和super指向:
this - 访问本类的成员
super - 访问父类的成员(可以理解为的)
class Fu {static {System.out.println("静态代码块Fu");}{System.out.println("构造代码块Fu");}public Fu() {System.out.println("构造方法Fu");}
}class Zi extends Fu {static {System.out.println("静态代码块Zi");}{System.out.println("构造代码块Zi");}public Zi() {System.out.println("构造方法Zi");}
}class ExtendsTest2 {public static void main(String[] args) {Zi z = new Zi();}
}
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
一个类的静态代码块,构造代码块,构造方法的执行流程
静态代码块 > 构造代码块 > 构造方法
父类静态代码块→子类静态代码块→父类构造代码块→父类构造方法→子类构造代码块→子类构造方法
解析
静态的内容是随着类的加载而加载:静态代码块的内容会优先执行。
构造代码块:在类中方法外出现(即在类中的成员位置),可以把多个构造方法方法中相同的代码存放到一起,用于对对象进行初始化。每次调用构造方法都执行,并且在构造方法前执行。
子类的所有的构造方法默认都会去访问父类的无参构造方法。
class X {//成员变量(引用类型)Y b = new Y();//无参构造方法X() {System.out.print("X");}
}class Y {//无参构造方法Y() {System.out.print("Y");}
}public class Z extends X {//成员变量(引用类型)Y y = new Y();//无参构造方法Z() {//super(); //它仅仅表示要先初始化父类数据,再初始化子类数据。System.out.print("Z");}public static void main(String[] args) {new Z();}
}
YXYZ
知识点:一个类的初始化过程
Student t = new Student();
创建一个对象都在内存中做了什么事情?
public interface A {default void show(){System.out.println("接口的方法");}
}
public class B {public void show(){System.out.println("优先调用类的方法");}
}
public class Test extends B implements A{public static void main(String[] args) {Test t = new Test();t.show(); //调用类的方法}
}
如果一个类同时继承了一个类和一个接口,如果类和接口内有相同的方法,那么创建对象调用的时候,会优先使用类的方法。如果子类重写,使用子类的方法
来源:https://www.runoob.com/w3cnote/java-extends.html
面试题来源:https://www.cnblogs.com/chenmingjun/p/8449506.html
一个类的初始化过程:https://blog.csdn.net/weixin_42638178/article/details/115805522