Java基礎(chǔ)之super關(guān)鍵字淺析
本文重點(diǎn)介紹super關(guān)鍵字,在Java中的作用以及用法。
一、定義
它是一個(gè)指代變量,用于在子類(lèi)中指代父類(lèi)對(duì)象。
二、應(yīng)用
2.1 應(yīng)用范圍
只能用于子類(lèi)的構(gòu)造函數(shù)和實(shí)例方法中,不能用于子類(lèi)的類(lèi)(靜態(tài))方法中。原因是super指代的是一個(gè)父類(lèi)的對(duì)象,它需要在運(yùn)行時(shí)被創(chuàng)建,而靜態(tài)方法是類(lèi)方法,它是類(lèi)的一部分。當(dāng)類(lèi)被加載時(shí),方法已經(jīng)存在,但是這時(shí)候父類(lèi)對(duì)象還沒(méi)有被初始化。
2.2 用法
在Java中super有兩種使用場(chǎng)景。
2.2.1 在子類(lèi)中調(diào)用父類(lèi)的屬性或方法
在子類(lèi)中調(diào)用父類(lèi)的屬性或方法。特別是子類(lèi)中有與父類(lèi)相同的屬性或者方法,那么這時(shí)如果你想調(diào)用父類(lèi)的屬性或者方法,那么你必須使用super關(guān)鍵字。因?yàn)樽宇?lèi)中和父類(lèi)中的屬性或方法同名,則父類(lèi)中的方法或?qū)傩詫⒈桓采w或隱藏。super可以指代父類(lèi)中的類(lèi)屬性和類(lèi)方法,但是并不建議這么用,雖然不會(huì)報(bào)錯(cuò),但是說(shuō)明你對(duì)static關(guān)鍵字還不夠了解。請(qǐng)認(rèn)真查看并理解static關(guān)鍵字。
public class Parent {
public String name = "小頭爸爸";
public boolean hasMoney = false;
public void sleeping(){
System.out.println("爸爸已經(jīng)睡了");
}
public void working(){
System.out.println("爸爸正在工作。。。");
}
}
public class Child extends Parent {
public String name = "大頭兒子";
/**
* 當(dāng)子類(lèi)和父類(lèi)有屬性重名時(shí),需要super才能調(diào)用到父類(lèi)的屬性,
* 直接調(diào)用會(huì)調(diào)用到子類(lèi)的屬性
* 如果不重名,可直接調(diào)用且調(diào)用的是父類(lèi)的屬性
*/
private void testParam(){
System.out.println("爸爸的名字叫" + super.name);
System.out.println("孩子的名字是" + name);
System.out.println("爸爸是否有有錢(qián):" + hasMoney);
}
/**
* 方法和上面的屬性結(jié)果一樣
*/
public void testMethod(){
sleeping();
super.sleeping();
super.working();
}
public void sleeping(){
System.out.println("兒子已經(jīng)睡了");
}
public static void main(String[] args) {
Child child = new Child();
child.testParam();
child.testMethod();
}
}測(cè)試結(jié)果:
=============
爸爸的名字叫小頭爸爸
孩子的名字是大頭兒子
爸爸是否有有錢(qián):false
兒子已經(jīng)睡了
爸爸已經(jīng)睡了爸爸正在工作。。。
============
2.2.2 在子類(lèi)中指代父類(lèi)構(gòu)造器
在Java中,子類(lèi)是父類(lèi)的派生類(lèi),它的實(shí)例化依賴(lài)于父類(lèi)的實(shí)例化。所以它的任何一個(gè)構(gòu)造函數(shù)都必須要初始化父類(lèi),Java就是super關(guān)鍵字調(diào)用父類(lèi)構(gòu)造方法,來(lái)完成這個(gè)操作。
有人會(huì)奇怪,那為什么在2.1.1的例子,父類(lèi)沒(méi)有構(gòu)造方法,子類(lèi)也沒(méi)有構(gòu)造方法,難道在某些情況下,實(shí)例的初始化并不依賴(lài)于構(gòu)造函數(shù)?
答案是,實(shí)例的初始化必須要構(gòu)造函數(shù)。2.2.1沒(méi)有構(gòu)造函數(shù)的原因是,在Java類(lèi)定義中,如果開(kāi)發(fā)者沒(méi)有顯示的定義構(gòu)造函數(shù),那么Java會(huì)隱式的為該類(lèi)定義一個(gè)無(wú)參構(gòu)造函數(shù)。但是如果開(kāi)發(fā)者自己定一個(gè)構(gòu)造函數(shù)(無(wú)論有參還是無(wú)參),那么Java就不會(huì)再為該類(lèi)隱式的定義一個(gè)無(wú)參構(gòu)造函數(shù)了。
那么還原構(gòu)造函數(shù)后的代碼:
public class Parent {
...
public Parent() {
}
...
}
public class Child extends Parent {
...
public Child() {
}
...
}那么又有人有奇怪了,你不是說(shuō)子類(lèi)的實(shí)例化依賴(lài)于父類(lèi)的實(shí)例化,那么在子類(lèi)的構(gòu)造函數(shù)中應(yīng)該需要調(diào)用super來(lái)初始化父類(lèi)不是嗎?
是的,在我們子類(lèi)的構(gòu)造函數(shù)中,如果我們沒(méi)有顯式調(diào)用super來(lái)初始化父類(lèi)的話(huà),那么Java會(huì)隱式的調(diào)用super();來(lái)調(diào)用父類(lèi)無(wú)參構(gòu)造函數(shù)并把它放在構(gòu)造函數(shù)的第一行。記住哦,Java只會(huì)隱式的調(diào)用無(wú)參構(gòu)造函數(shù),如果父類(lèi)沒(méi)有無(wú)參構(gòu)造函數(shù),那么子類(lèi)中就必須顯示的調(diào)用super關(guān)鍵字來(lái)調(diào)用已有的有參構(gòu)造函數(shù)來(lái)初始化父類(lèi)。
public class Parent {
public String name = "小頭爸爸";
public Parent(int age) {
}
public void sleeping(){
System.out.println("爸爸已經(jīng)睡了");
}
}
public class Child extends Parent {
public String name = "大頭兒子";
public Child() {//如果沒(méi)有super來(lái)初始化父類(lèi),同樣也會(huì)報(bào)錯(cuò)
// super();//編譯期報(bào)錯(cuò),因?yàn)楦割?lèi)并沒(méi)有無(wú)參構(gòu)造函數(shù)
super(15);//正確打開(kāi)方式
}
private void printParentName(){
System.out.println("爸爸的名字叫" + super.name);
}
private void parentStatus(){
super.sleeping();
}
}子類(lèi)中的super為什么必須要放在第一行?因?yàn)樽宇?lèi)的實(shí)例化依賴(lài)于父類(lèi)的實(shí)例化,在構(gòu)建子類(lèi)時(shí),必須要有父類(lèi)實(shí)例,只能有了父類(lèi)的實(shí)例,子類(lèi)才能夠初始化自己。就好像人類(lèi)世界里,都是要先有父親,再有孩子一樣。
附:super實(shí)際使用示例
下面來(lái)看看super關(guān)鍵字的實(shí)際用法。 在這里,Emp類(lèi)繼承了Person類(lèi),所以Person的所有屬性都將默認(rèn)繼承到Emp。 要初始化所有的屬性,可使用子類(lèi)的父類(lèi)構(gòu)造函數(shù)。 這樣,我們重用了父類(lèi)的構(gòu)造函數(shù)。
class Person {
? ? int id;
? ? String name;
? ? Person(int id, String name) {
? ? ? ? this.id = id;
? ? ? ? this.name = name;
? ? }
}
class Emp extends Person {
? ? float salary;
? ? Emp(int id, String name, float salary) {
? ? ? ? super(id, name);// reusing parent constructor
? ? ? ? this.salary = salary;
? ? }
? ? void display() {
? ? ? ? System.out.println(id + " " + name + " " + salary);
? ? }
}
class TestSuper5 {
? ? public static void main(String[] args) {
? ? ? ? Emp e1 = new Emp(1, "ankit", 45000f);
? ? ? ? e1.display();
? ? }
}結(jié)果如下:
1 ankit 45000
總結(jié)
super關(guān)鍵字指代父類(lèi)對(duì)象,主要用于在子類(lèi)中指定父類(lèi)的方法和屬性,也用于在子類(lèi)中初始化父類(lèi)。子類(lèi)的靜態(tài)方法中不能使用super關(guān)鍵字。
到此這篇關(guān)于Java基礎(chǔ)之super關(guān)鍵字的文章就介紹到這了,更多相關(guān)Java super關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決 Spring RestTemplate post傳遞參數(shù)時(shí)報(bào)錯(cuò)問(wèn)題
本文詳解說(shuō)明了RestTemplate post傳遞參數(shù)時(shí)報(bào)錯(cuò)的問(wèn)題及其原由,需要的朋友可以參考下2020-02-02
Java創(chuàng)建多線(xiàn)程的幾種方式實(shí)現(xiàn)
這篇文章主要介紹了Java創(chuàng)建多線(xiàn)程的幾種方式實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
Java實(shí)現(xiàn)Excel百萬(wàn)級(jí)數(shù)據(jù)導(dǎo)入功能的示例代碼
這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)Excel百萬(wàn)級(jí)數(shù)據(jù)導(dǎo)入功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下2024-04-04
Java基于遞歸和循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積算法示例
這篇文章主要介紹了Java基于遞歸和循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積算法,結(jié)合實(shí)例形式分析了Java使用遞歸與循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積相關(guān)概念、原理與操作技巧,需要的朋友可以參考下2017-12-12
Java接口的作用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java接口的作用,涉及到接口的規(guī)范相關(guān)知識(shí),需要的的朋友參考下2017-04-04
openFeign服務(wù)之間調(diào)用保持請(qǐng)求頭信息處理方式
這篇文章主要介紹了openFeign服務(wù)之間調(diào)用保持請(qǐng)求頭信息處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06

