Java?中的?super?關(guān)鍵字用法指南
個(gè)人總結(jié):
1.子類(lèi)構(gòu)造方法中沒(méi)有顯式使用super,Java 也會(huì)默認(rèn)調(diào)用父類(lèi)的無(wú)參構(gòu)造方法
2.當(dāng)父類(lèi)中沒(méi)有無(wú)參構(gòu)造方法,只有有參構(gòu)造方法時(shí),子類(lèi)構(gòu)造方法就必須顯式地使用super來(lái)調(diào)用父類(lèi)的有參構(gòu)造方法。
3.如果父類(lèi)沒(méi)有定義任何構(gòu)造方法,編譯器會(huì)自動(dòng)為父類(lèi)生成一個(gè)無(wú)參構(gòu)造方法。但如果父類(lèi)已經(jīng)定義了有參構(gòu)造方法,編譯器不會(huì)自動(dòng)生成無(wú)參構(gòu)造方法,此時(shí)子類(lèi)必須顯式調(diào)用父類(lèi)的有參構(gòu)造方法。
在 Java 的面向?qū)ο缶幊淌澜缋?,繼承是一個(gè)極為重要的特性,它讓代碼得以復(fù)用和擴(kuò)展,構(gòu)建出層次分明的類(lèi)體系。而super關(guān)鍵字,就像是一把神奇的鑰匙,在繼承的場(chǎng)景中發(fā)揮著不可或缺的作用。它能夠幫助我們輕松訪問(wèn)父類(lèi)的成員,理解和掌握super關(guān)鍵字,對(duì)于編寫(xiě)高效、健壯的 Java 代碼至關(guān)重要。接下來(lái),我們就深入探究一下super關(guān)鍵字的奧秘。?
一、super 關(guān)鍵字的基本概念?
super是 Java 中的一個(gè)關(guān)鍵字,它主要用于在子類(lèi)中訪問(wèn)父類(lèi)的成員,包括成員變量、成員方法以及構(gòu)造方法 。需要明確的是,super代表的是對(duì)當(dāng)前對(duì)象父類(lèi)對(duì)象的引用,但它并不像普通對(duì)象引用那樣可以隨意使用,它有著特定的使用場(chǎng)景和規(guī)則。?
二、super 調(diào)用父類(lèi)構(gòu)造方法?
在類(lèi)的繼承關(guān)系中,當(dāng)創(chuàng)建子類(lèi)對(duì)象時(shí),會(huì)先調(diào)用父類(lèi)的構(gòu)造方法,然后再調(diào)用子類(lèi)自身的構(gòu)造方法,這是 Java 對(duì)象初始化的一個(gè)重要機(jī)制。而super關(guān)鍵字可以在子類(lèi)構(gòu)造方法中顯式地調(diào)用父類(lèi)的構(gòu)造方法。?
1. 無(wú)參構(gòu)造方法調(diào)用?
先來(lái)看一個(gè)簡(jiǎn)單的例子,定義一個(gè)父類(lèi)Animal:
class Animal {
public Animal() {
System.out.println("Animal類(lèi)的無(wú)參構(gòu)造方法被調(diào)用");
}
}再定義一個(gè)子類(lèi)Dog繼承自Animal:
class Dog extends Animal {
public Dog() {
System.out.println("Dog類(lèi)的無(wú)參構(gòu)造方法被調(diào)用");
}
}在測(cè)試類(lèi)中創(chuàng)建Dog對(duì)象:
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
}
}運(yùn)行結(jié)果為:
Animal類(lèi)的無(wú)參構(gòu)造方法被調(diào)用
Dog類(lèi)的無(wú)參構(gòu)造方法被調(diào)用
可以看到,在創(chuàng)建Dog對(duì)象時(shí),即使子類(lèi)構(gòu)造方法中沒(méi)有顯式使用super,Java 也會(huì)默認(rèn)調(diào)用父類(lèi)的無(wú)參構(gòu)造方法。這是 Java 的一個(gè)隱式規(guī)則,目的是確保父類(lèi)對(duì)象先完成初始化,為子類(lèi)對(duì)象的初始化提供基礎(chǔ)。
2. 有參構(gòu)造方法調(diào)用?
當(dāng)父類(lèi)中沒(méi)有無(wú)參構(gòu)造方法,只有有參構(gòu)造方法時(shí),子類(lèi)構(gòu)造方法就必須顯式地使用super來(lái)調(diào)用父類(lèi)的有參構(gòu)造方法。例如,修改Animal類(lèi):
class Animal {
private String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal類(lèi)的有參構(gòu)造方法被調(diào)用,動(dòng)物名稱(chēng):" + name);
}
}然后修改Dog類(lèi)的構(gòu)造方法:
class Dog extends Animal {
public Dog(String name) {
super(name);
System.out.println("Dog類(lèi)的有參構(gòu)造方法被調(diào)用");
}
}測(cè)試代碼如下:
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("旺財(cái)");
}
}運(yùn)行結(jié)果:
Animal類(lèi)的有參構(gòu)造方法被調(diào)用,動(dòng)物名稱(chēng):旺財(cái)
Dog類(lèi)的有參構(gòu)造方法被調(diào)用
在子類(lèi)Dog的構(gòu)造方法中,super(name)這行代碼明確指定了調(diào)用父類(lèi)Animal的有參構(gòu)造方法,并將參數(shù)傳遞過(guò)去,這樣才能正確完成對(duì)象的初始化過(guò)程。同時(shí)要注意,super調(diào)用父類(lèi)構(gòu)造方法的語(yǔ)句必須是子類(lèi)構(gòu)造方法的第一行代碼 ,否則會(huì)編譯報(bào)錯(cuò)。?
三、super 訪問(wèn)父類(lèi)成員變量?
當(dāng)子類(lèi)中定義了與父類(lèi)同名的成員變量時(shí),如果在子類(lèi)中直接訪問(wèn)該變量名,默認(rèn)訪問(wèn)的是子類(lèi)自身的成員變量。此時(shí),如果想要訪問(wèn)父類(lèi)的同名成員變量,就可以使用super關(guān)鍵字。?
定義父類(lèi)Person:
class Person {
String name = "父類(lèi)的姓名";
}定義子類(lèi)Student繼承自Person:
class Student extends Person {
String name = "子類(lèi)的姓名";
public void printNames() {
System.out.println("子類(lèi)的name:" + name);
System.out.println("父類(lèi)的name:" + super.name);
}
}測(cè)試代碼:
public class Main {
public static void main(String[] args) {
Student student = new Student();
student.printNames();
}
}運(yùn)行結(jié)果:
子類(lèi)的name:子類(lèi)的姓名
父類(lèi)的name:父類(lèi)的姓名
通過(guò)super.name,我們?cè)谧宇?lèi)Student中成功訪問(wèn)到了父類(lèi)Person的成員變量name,避免了變量訪問(wèn)的混淆。?
四、super 調(diào)用父類(lèi)成員方法?
同樣,當(dāng)子類(lèi)重寫(xiě)了父類(lèi)的方法時(shí),如果在子類(lèi)中想要調(diào)用父類(lèi)被重寫(xiě)的方法,也可以借助super關(guān)鍵字。?
定義父類(lèi)Vehicle:
class Vehicle {
public void run() {
System.out.println("車(chē)輛在行駛");
}
}定義子類(lèi)Car繼承自Vehicle并重寫(xiě)run方法:
class Car extends Vehicle {
@Override
public void run() {
super.run();
System.out.println("汽車(chē)在馬路上快速行駛");
}
}測(cè)試代碼:
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.run();
}
}運(yùn)行結(jié)果:
車(chē)輛在行駛
汽車(chē)在馬路上快速行駛
在子類(lèi)Car的run方法中,super.run()調(diào)用了父類(lèi)Vehicle的run方法,這樣既保留了父類(lèi)方法的功能,又在其基礎(chǔ)上進(jìn)行了擴(kuò)展,實(shí)現(xiàn)了代碼的復(fù)用和增強(qiáng)。
五、父類(lèi)定義有參、無(wú)參構(gòu)造方法的各種情況
在 Java 中,如果父類(lèi)沒(méi)有定義任何構(gòu)造方法,編譯器會(huì)自動(dòng)為父類(lèi)生成一個(gè)無(wú)參構(gòu)造方法。但如果父類(lèi)已經(jīng)定義了有參構(gòu)造方法,編譯器不會(huì)自動(dòng)生成無(wú)參構(gòu)造方法,此時(shí)子類(lèi)必須顯式調(diào)用父類(lèi)的有參構(gòu)造方法。
1.關(guān)鍵規(guī)則總結(jié):
| 父類(lèi)情況 | 子類(lèi)構(gòu)造方法中是否顯式調(diào)用super() | 結(jié)果 |
|---|---|---|
| 有無(wú)參構(gòu)造方法 | 未顯式調(diào)用super() | 編譯器自動(dòng)插入super();(調(diào)用父類(lèi)無(wú)參構(gòu)造) |
| 有參構(gòu)造方法但沒(méi)有無(wú)參構(gòu)造方法 | 未顯式調(diào)用super() | ? 編譯錯(cuò)誤:找不到父類(lèi)的無(wú)參構(gòu)造方法 |
| 有參構(gòu)造方法但沒(méi)有無(wú)參構(gòu)造方法 | 顯式調(diào)用super(參數(shù)); | ? 正確:調(diào)用父類(lèi)的有參構(gòu)造方法 |
2.示例代碼分析
父類(lèi)沒(méi)有定義任何構(gòu)造方法
class Parent {
// 編譯器會(huì)自動(dòng)添加無(wú)參構(gòu)造方法:
// public Parent() {}
}
class Child extends Parent {
public Child() {
// 編譯器會(huì)自動(dòng)插入 super();
}
}父類(lèi)只有有參構(gòu)造方法
class Parent {
public Parent(int value) { // 定義了有參構(gòu)造方法
// ...
}
// 注意:編譯器不會(huì)自動(dòng)生成無(wú)參構(gòu)造方法!
}
class Child extends Parent {
public Child() {
// ? 編譯錯(cuò)誤:沒(méi)有super(),但父類(lèi)沒(méi)有無(wú)參構(gòu)造方法
}
public Child(int value) {
super(value); // ? 必須顯式調(diào)用父類(lèi)的有參構(gòu)造方法
}
}3. 常見(jiàn)錯(cuò)誤案例
以下代碼會(huì)導(dǎo)致編譯錯(cuò)誤:
class Animal {
private String name;
public Animal(String name) { // 父類(lèi)只有有參構(gòu)造
this.name = name;
}
}
class Dog extends Animal {
public Dog() {
// ? 編譯錯(cuò)誤:沒(méi)有super(),但父類(lèi)沒(méi)有無(wú)參構(gòu)造
}
}修正方式:在子類(lèi)構(gòu)造方法中顯式調(diào)用父類(lèi)的有參構(gòu)造方法
class Dog extends Animal {
public Dog(String name) {
super(name); // ? 顯式調(diào)用父類(lèi)的有參構(gòu)造
}
}六、super( )詳解
1.super() 是什么?
在 Java 中,super()是子類(lèi)構(gòu)造方法中調(diào)用父類(lèi)構(gòu)造方法的特殊語(yǔ)法。它必須是子類(lèi)構(gòu)造方法的第一行代碼。
2.為什么需要 super()?
當(dāng)創(chuàng)建子類(lèi)對(duì)象時(shí),Java 會(huì)先初始化父類(lèi)的部分。通過(guò)super(),我們可以顯式指定如何初始化父類(lèi)的狀態(tài)。
3.最簡(jiǎn)單的示例
下面是一個(gè)基礎(chǔ)示例,展示super()的基本用法:
// 父類(lèi):動(dòng)物
class Animal {
private String name;
// 父類(lèi)的構(gòu)造方法
public Animal(String name) {
this.name = name;
System.out.println("創(chuàng)建了一只動(dòng)物:" + name);
}
public String getName() {
return name;
}
}
// 子類(lèi):狗
class Dog extends Animal {
private String breed;
// 子類(lèi)的構(gòu)造方法
public Dog(String name, String breed) {
super(name); // 調(diào)用父類(lèi)的構(gòu)造方法,必須在第一行
this.breed = breed;
System.out.println("這是一只" + breed + ":" + name);
}
public String getBreed() {
return breed;
}
}
// 測(cè)試類(lèi)
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("旺財(cái)", "金毛");
System.out.println(dog.getName() + "是一只" + dog.getBreed());
}
} 
4.關(guān)鍵代碼解釋
父類(lèi)構(gòu)造方法:
public Animal(String name) {
this.name = name;
}Animal類(lèi)的構(gòu)造方法接收一個(gè)name參數(shù),用于初始化動(dòng)物的名稱(chēng)。
子類(lèi)構(gòu)造方法中的super():
public Dog(String name, String breed) {
super(name); // 調(diào)用父類(lèi)構(gòu)造方法,初始化name
this.breed = breed; // 初始化子類(lèi)特有的屬性
}super(name)將name參數(shù)傳遞給父類(lèi)的構(gòu)造方法,確保父類(lèi)的name字段被正確初始化。
如果省略super(name),Java 會(huì)默認(rèn)調(diào)用父類(lèi)的無(wú)參構(gòu)造方法(如果存在)。
5.執(zhí)行流程
當(dāng)執(zhí)行Dog dog = new Dog("旺財(cái)", "金毛");時(shí):
- 調(diào)用子類(lèi)構(gòu)造方法:
Dog(String name, String breed)- 隱式 / 顯式調(diào)用父類(lèi)構(gòu)造方法:
- 通過(guò)
super(name)調(diào)用Animal(String name)- 父類(lèi)初始化完成:
Animal的name字段被設(shè)置為 "旺財(cái)"- 繼續(xù)執(zhí)行子類(lèi)構(gòu)造方法:
this.breed = breed將breed設(shè)置為 "金毛"
到此這篇關(guān)于Java 中的 super 關(guān)鍵字的文章就介紹到這了,更多相關(guān)Java super 關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 一文詳細(xì)講解Java的父子繼承、方法的重寫(xiě)與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中比較常見(jiàn)的Java super關(guān)鍵字
相關(guān)文章
深入了解Java數(shù)據(jù)結(jié)構(gòu)和算法之堆
這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之堆 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-01-01
No ‘Access-Control-Allow-Origin‘ header is&nb
這篇文章主要介紹了No ‘Access-Control-Allow-Origin‘ header is present跨域及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
SpringBoot2.X整合Spring-Cache緩存開(kāi)發(fā)的實(shí)現(xiàn)
本文主要介紹了SpringBoot2.X整合Spring-Cache緩存開(kāi)發(fā)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Java怎樣創(chuàng)建集合才能避免造成內(nèi)存泄漏你了解嗎
內(nèi)存泄漏是指無(wú)用對(duì)象持續(xù)占有內(nèi)存或無(wú)用對(duì)象的內(nèi)存得不到及時(shí)釋放,從而造成內(nèi)存空間的浪費(fèi)稱(chēng)為內(nèi)存泄漏。長(zhǎng)生命周期的對(duì)象持有短生命周期對(duì)象的引用就很可能發(fā)生內(nèi)存泄漏,盡管短生命周期對(duì)象已經(jīng)不再需要,但是因?yàn)殚L(zhǎng)生命周期持有它的引用而導(dǎo)致不能被回收2021-09-09
Java中多個(gè)線程交替循環(huán)執(zhí)行的實(shí)現(xiàn)
有些時(shí)候面試官經(jīng)常會(huì)問(wèn),兩個(gè)線程怎么交替執(zhí)行呀,本文就來(lái)詳細(xì)的介紹一下Java中多個(gè)線程交替循環(huán)執(zhí)行的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01

