一、父类空间优先于子类对象产生
在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。
代码体现在子类的构造方法调用时,一定先调用父类的构造方法。理解图解如下:
例子:
/** * 自定义异常类 */ @Setter @Getter @AllArgsConstructor @NoArgsConstructor public class CustomException extends RuntimeException { /** * 错误码 */ protected Integer errorCode; /** * 错误信息 */ protected String errorMsg; public CustomException(String errorMsg) { super(errorMsg); this.errorMsg = errorMsg; } public CustomException(Integer errorCode, String errorMsg, Throwable cause) { super(errorCode.toString(), cause); this.errorCode = errorCode; this.errorMsg = errorMsg; } @Override public synchronized Throwable fillInStackTrace() { return this; } }
super :代表父类的存储空间标识(可以理解为父亲的引用)。
this :代表当前对象的引用(谁调用就代表谁)。
三、super和this的用法
1、访问成员
this.成员变量 ‐‐ 本类的 super.成员变量 ‐‐ 父类的 this.成员方法名() ‐‐ 本类的 super.成员方法名() ‐‐ 父类的
2、访问构造方法
this(...) ‐‐ 本类的构造方法 super(...) ‐‐ 父类的构造方法
例子
public class JwtUtil { // 创建默认的秘钥和算法,供无参的构造方法使用 private static final String defaultbase64EncodedSecretKey = "xxx"; private static final SignatureAlgorithm defaultsignatureAlgorithm = SignatureAlgorithm.HS256; public JwtUtil() { this(defaultbase64EncodedSecretKey, defaultsignatureAlgorithm); } private final String base64EncodedSecretKey; private final SignatureAlgorithm signatureAlgorithm; public JwtUtil(String secretKey, SignatureAlgorithm signatureAlgorithm) { this.base64EncodedSecretKey = Base64.encodeBase64String(secretKey.getBytes()); this.signatureAlgorithm = signatureAlgorithm; } }
注意:
1)、子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。
2)、super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。
例子:
class Animal { public void eat() { System.out.println("animal : eat"); } } class Cat extends Animal { public void eat() { System.out.println("cat : eat"); } public void eatTest() { this.eat(); // this 调用本类的方法 super.eat(); // super 调用父类的方法 } } public class ExtendsDemo08 { public static void main(String[] args) { Animal a = new Animal(); a.eat(); Cat c = new Cat(); c.eatTest(); } }
输出结果为:
animal : eat
cat : eat
animal : eat