Java?中的?super?關(guān)鍵字用法指南
個人總結(jié):
1.子類構(gòu)造方法中沒有顯式使用super,Java 也會默認(rèn)調(diào)用父類的無參構(gòu)造方法
2.當(dāng)父類中沒有無參構(gòu)造方法,只有有參構(gòu)造方法時,子類構(gòu)造方法就必須顯式地使用super來調(diào)用父類的有參構(gòu)造方法。
3.如果父類沒有定義任何構(gòu)造方法,編譯器會自動為父類生成一個無參構(gòu)造方法。但如果父類已經(jīng)定義了有參構(gòu)造方法,編譯器不會自動生成無參構(gòu)造方法,此時子類必須顯式調(diào)用父類的有參構(gòu)造方法。
在 Java 的面向?qū)ο缶幊淌澜缋?,繼承是一個極為重要的特性,它讓代碼得以復(fù)用和擴(kuò)展,構(gòu)建出層次分明的類體系。而super關(guān)鍵字,就像是一把神奇的鑰匙,在繼承的場景中發(fā)揮著不可或缺的作用。它能夠幫助我們輕松訪問父類的成員,理解和掌握super關(guān)鍵字,對于編寫高效、健壯的 Java 代碼至關(guān)重要。接下來,我們就深入探究一下super關(guān)鍵字的奧秘。?
一、super 關(guān)鍵字的基本概念?
super是 Java 中的一個關(guān)鍵字,它主要用于在子類中訪問父類的成員,包括成員變量、成員方法以及構(gòu)造方法 。需要明確的是,super代表的是對當(dāng)前對象父類對象的引用,但它并不像普通對象引用那樣可以隨意使用,它有著特定的使用場景和規(guī)則。?
二、super 調(diào)用父類構(gòu)造方法?
在類的繼承關(guān)系中,當(dāng)創(chuàng)建子類對象時,會先調(diào)用父類的構(gòu)造方法,然后再調(diào)用子類自身的構(gòu)造方法,這是 Java 對象初始化的一個重要機(jī)制。而super關(guān)鍵字可以在子類構(gòu)造方法中顯式地調(diào)用父類的構(gòu)造方法。?
1. 無參構(gòu)造方法調(diào)用?
先來看一個簡單的例子,定義一個父類Animal:
class Animal {
public Animal() {
System.out.println("Animal類的無參構(gòu)造方法被調(diào)用");
}
}再定義一個子類Dog繼承自Animal:
class Dog extends Animal {
public Dog() {
System.out.println("Dog類的無參構(gòu)造方法被調(diào)用");
}
}在測試類中創(chuàng)建Dog對象:
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
}
}運(yùn)行結(jié)果為:
Animal類的無參構(gòu)造方法被調(diào)用
Dog類的無參構(gòu)造方法被調(diào)用
可以看到,在創(chuàng)建Dog對象時,即使子類構(gòu)造方法中沒有顯式使用super,Java 也會默認(rèn)調(diào)用父類的無參構(gòu)造方法。這是 Java 的一個隱式規(guī)則,目的是確保父類對象先完成初始化,為子類對象的初始化提供基礎(chǔ)。
2. 有參構(gòu)造方法調(diào)用?
當(dāng)父類中沒有無參構(gòu)造方法,只有有參構(gòu)造方法時,子類構(gòu)造方法就必須顯式地使用super來調(diào)用父類的有參構(gòu)造方法。例如,修改Animal類:
class Animal {
private String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal類的有參構(gòu)造方法被調(diào)用,動物名稱:" + name);
}
}然后修改Dog類的構(gòu)造方法:
class Dog extends Animal {
public Dog(String name) {
super(name);
System.out.println("Dog類的有參構(gòu)造方法被調(diào)用");
}
}測試代碼如下:
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("旺財");
}
}運(yùn)行結(jié)果:
Animal類的有參構(gòu)造方法被調(diào)用,動物名稱:旺財
Dog類的有參構(gòu)造方法被調(diào)用
在子類Dog的構(gòu)造方法中,super(name)這行代碼明確指定了調(diào)用父類Animal的有參構(gòu)造方法,并將參數(shù)傳遞過去,這樣才能正確完成對象的初始化過程。同時要注意,super調(diào)用父類構(gòu)造方法的語句必須是子類構(gòu)造方法的第一行代碼 ,否則會編譯報錯。?
三、super 訪問父類成員變量?
當(dāng)子類中定義了與父類同名的成員變量時,如果在子類中直接訪問該變量名,默認(rèn)訪問的是子類自身的成員變量。此時,如果想要訪問父類的同名成員變量,就可以使用super關(guān)鍵字。?
定義父類Person:
class Person {
String name = "父類的姓名";
}定義子類Student繼承自Person:
class Student extends Person {
String name = "子類的姓名";
public void printNames() {
System.out.println("子類的name:" + name);
System.out.println("父類的name:" + super.name);
}
}測試代碼:
public class Main {
public static void main(String[] args) {
Student student = new Student();
student.printNames();
}
}運(yùn)行結(jié)果:
子類的name:子類的姓名
父類的name:父類的姓名
通過super.name,我們在子類Student中成功訪問到了父類Person的成員變量name,避免了變量訪問的混淆。?
四、super 調(diào)用父類成員方法?
同樣,當(dāng)子類重寫了父類的方法時,如果在子類中想要調(diào)用父類被重寫的方法,也可以借助super關(guān)鍵字。?
定義父類Vehicle:
class Vehicle {
public void run() {
System.out.println("車輛在行駛");
}
}定義子類Car繼承自Vehicle并重寫run方法:
class Car extends Vehicle {
@Override
public void run() {
super.run();
System.out.println("汽車在馬路上快速行駛");
}
}測試代碼:
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.run();
}
}運(yùn)行結(jié)果:
車輛在行駛
汽車在馬路上快速行駛
在子類Car的run方法中,super.run()調(diào)用了父類Vehicle的run方法,這樣既保留了父類方法的功能,又在其基礎(chǔ)上進(jìn)行了擴(kuò)展,實現(xiàn)了代碼的復(fù)用和增強(qiáng)。
五、父類定義有參、無參構(gòu)造方法的各種情況
在 Java 中,如果父類沒有定義任何構(gòu)造方法,編譯器會自動為父類生成一個無參構(gòu)造方法。但如果父類已經(jīng)定義了有參構(gòu)造方法,編譯器不會自動生成無參構(gòu)造方法,此時子類必須顯式調(diào)用父類的有參構(gòu)造方法。
1.關(guān)鍵規(guī)則總結(jié):
| 父類情況 | 子類構(gòu)造方法中是否顯式調(diào)用super() | 結(jié)果 |
|---|---|---|
| 有無參構(gòu)造方法 | 未顯式調(diào)用super() | 編譯器自動插入super();(調(diào)用父類無參構(gòu)造) |
| 有參構(gòu)造方法但沒有無參構(gòu)造方法 | 未顯式調(diào)用super() | ? 編譯錯誤:找不到父類的無參構(gòu)造方法 |
| 有參構(gòu)造方法但沒有無參構(gòu)造方法 | 顯式調(diào)用super(參數(shù)); | ? 正確:調(diào)用父類的有參構(gòu)造方法 |
2.示例代碼分析
父類沒有定義任何構(gòu)造方法
class Parent {
// 編譯器會自動添加無參構(gòu)造方法:
// public Parent() {}
}
class Child extends Parent {
public Child() {
// 編譯器會自動插入 super();
}
}父類只有有參構(gòu)造方法
class Parent {
public Parent(int value) { // 定義了有參構(gòu)造方法
// ...
}
// 注意:編譯器不會自動生成無參構(gòu)造方法!
}
class Child extends Parent {
public Child() {
// ? 編譯錯誤:沒有super(),但父類沒有無參構(gòu)造方法
}
public Child(int value) {
super(value); // ? 必須顯式調(diào)用父類的有參構(gòu)造方法
}
}3. 常見錯誤案例
以下代碼會導(dǎo)致編譯錯誤:
class Animal {
private String name;
public Animal(String name) { // 父類只有有參構(gòu)造
this.name = name;
}
}
class Dog extends Animal {
public Dog() {
// ? 編譯錯誤:沒有super(),但父類沒有無參構(gòu)造
}
}修正方式:在子類構(gòu)造方法中顯式調(diào)用父類的有參構(gòu)造方法
class Dog extends Animal {
public Dog(String name) {
super(name); // ? 顯式調(diào)用父類的有參構(gòu)造
}
}六、super( )詳解
1.super() 是什么?
在 Java 中,super()是子類構(gòu)造方法中調(diào)用父類構(gòu)造方法的特殊語法。它必須是子類構(gòu)造方法的第一行代碼。
2.為什么需要 super()?
當(dāng)創(chuàng)建子類對象時,Java 會先初始化父類的部分。通過super(),我們可以顯式指定如何初始化父類的狀態(tài)。
3.最簡單的示例
下面是一個基礎(chǔ)示例,展示super()的基本用法:
// 父類:動物
class Animal {
private String name;
// 父類的構(gòu)造方法
public Animal(String name) {
this.name = name;
System.out.println("創(chuàng)建了一只動物:" + name);
}
public String getName() {
return name;
}
}
// 子類:狗
class Dog extends Animal {
private String breed;
// 子類的構(gòu)造方法
public Dog(String name, String breed) {
super(name); // 調(diào)用父類的構(gòu)造方法,必須在第一行
this.breed = breed;
System.out.println("這是一只" + breed + ":" + name);
}
public String getBreed() {
return breed;
}
}
// 測試類
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("旺財", "金毛");
System.out.println(dog.getName() + "是一只" + dog.getBreed());
}
} 
4.關(guān)鍵代碼解釋
父類構(gòu)造方法:
public Animal(String name) {
this.name = name;
}Animal類的構(gòu)造方法接收一個name參數(shù),用于初始化動物的名稱。
子類構(gòu)造方法中的super():
public Dog(String name, String breed) {
super(name); // 調(diào)用父類構(gòu)造方法,初始化name
this.breed = breed; // 初始化子類特有的屬性
}super(name)將name參數(shù)傳遞給父類的構(gòu)造方法,確保父類的name字段被正確初始化。
如果省略super(name),Java 會默認(rèn)調(diào)用父類的無參構(gòu)造方法(如果存在)。
5.執(zhí)行流程
當(dāng)執(zhí)行Dog dog = new Dog("旺財", "金毛");時:
- 調(diào)用子類構(gòu)造方法:
Dog(String name, String breed)- 隱式 / 顯式調(diào)用父類構(gòu)造方法:
- 通過
super(name)調(diào)用Animal(String name)- 父類初始化完成:
Animal的name字段被設(shè)置為 "旺財"- 繼續(xù)執(zhí)行子類構(gòu)造方法:
this.breed = breed將breed設(shè)置為 "金毛"
到此這篇關(guān)于Java 中的 super 關(guān)鍵字的文章就介紹到這了,更多相關(guān)Java super 關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 一文詳細(xì)講解Java的父子繼承、方法的重寫與super關(guān)鍵字
- Java關(guān)鍵字super超詳細(xì)解釋
- java關(guān)鍵字super的騷操作詳解
- Java關(guān)鍵字this與super詳解用法
- Java中super關(guān)鍵字介紹以及super()的使用
- Java super關(guān)鍵字的用法詳解
- Java繼承extends與super關(guān)鍵字詳解
- Java super關(guān)鍵字的使用方法詳解
- 舉例講解Java編程中this關(guān)鍵字與super關(guān)鍵字的用法
- Android中比較常見的Java super關(guān)鍵字
相關(guān)文章
解決SpringAop內(nèi)部調(diào)用時不經(jīng)過代理類的問題
這篇文章主要介紹了解決SpringAop內(nèi)部調(diào)用時不經(jīng)過代理類的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringBoot?使用?Sa-Token?完成注解鑒權(quán)功能(權(quán)限校驗)
Sa-Token?是一個輕量級?java?權(quán)限認(rèn)證框架,主要解決登錄認(rèn)證、權(quán)限認(rèn)證、單點(diǎn)登錄、OAuth2、微服務(wù)網(wǎng)關(guān)鑒權(quán)?等一系列權(quán)限相關(guān)問題,這篇文章主要介紹了SpringBoot使用Sa-Token完成注解鑒權(quán)功能,需要的朋友可以參考下2023-05-05
Java 并發(fā)編程學(xué)習(xí)筆記之Synchronized底層優(yōu)化
這篇文章主要介紹了Java 并發(fā)編程學(xué)習(xí)筆記之Synchronized底層優(yōu)化的相關(guān)資料,主要包含了重量級鎖,輕量級鎖,偏向鎖和其他優(yōu)化等方面,有需要的小伙伴可以參考下2016-05-05
Java中使用JavaMail多發(fā)郵件及郵件的驗證和附件實現(xiàn)
這篇文章主要介紹了Java中使用Java Mail多發(fā)郵件及郵件的驗證和附件實現(xiàn),包括在郵件中加入圖片等功能的實現(xiàn)講解,需要的朋友可以參考下2016-02-02
Spring Boot實戰(zhàn)之發(fā)送郵件示例代碼
本篇文章主要介紹了Spring Boot實戰(zhàn)之發(fā)送郵件示例代碼,具有一定的參考價值,有興趣的可以了解一下。2017-03-03
防止SpringMVC攔截器攔截js等靜態(tài)資源文件的解決方法
本篇文章主要介紹了防止SpringMVC攔截器攔截js等靜態(tài)資源文件的解決方法,具有一定的參考價值,有興趣的同學(xué)可以了解一下2017-09-09
java 重定義數(shù)組的實現(xiàn)方法(與VB的ReDim相像)
java 重定義數(shù)組的實現(xiàn)方法(與VB的ReDim相像),需要的朋友可以參考一下2013-04-04

