Java基礎(chǔ)之super關(guān)鍵字淺析
本文重點(diǎn)介紹super關(guān)鍵字,在Java中的作用以及用法。
一、定義
它是一個(gè)指代變量,用于在子類中指代父類對象。
二、應(yīng)用
2.1 應(yīng)用范圍
只能用于子類的構(gòu)造函數(shù)和實(shí)例方法中,不能用于子類的類(靜態(tài))方法中。原因是super指代的是一個(gè)父類的對象,它需要在運(yùn)行時(shí)被創(chuàng)建,而靜態(tài)方法是類方法,它是類的一部分。當(dāng)類被加載時(shí),方法已經(jīng)存在,但是這時(shí)候父類對象還沒有被初始化。
2.2 用法
在Java中super有兩種使用場景。
2.2.1 在子類中調(diào)用父類的屬性或方法
在子類中調(diào)用父類的屬性或方法。特別是子類中有與父類相同的屬性或者方法,那么這時(shí)如果你想調(diào)用父類的屬性或者方法,那么你必須使用super關(guān)鍵字。因?yàn)樽宇愔泻透割愔械膶傩曰蚍椒ㄍ?,則父類中的方法或?qū)傩詫⒈桓采w或隱藏。super可以指代父類中的類屬性和類方法,但是并不建議這么用,雖然不會(huì)報(bào)錯(cuò),但是說明你對static關(guān)鍵字還不夠了解。請認(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)子類和父類有屬性重名時(shí),需要super才能調(diào)用到父類的屬性, * 直接調(diào)用會(huì)調(diào)用到子類的屬性 * 如果不重名,可直接調(diào)用且調(diào)用的是父類的屬性 */ private void testParam(){ System.out.println("爸爸的名字叫" + super.name); System.out.println("孩子的名字是" + name); System.out.println("爸爸是否有有錢:" + 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(); } }
測試結(jié)果:
=============
爸爸的名字叫小頭爸爸
孩子的名字是大頭兒子
爸爸是否有有錢:false
兒子已經(jīng)睡了
爸爸已經(jīng)睡了爸爸正在工作。。。
============
2.2.2 在子類中指代父類構(gòu)造器
在Java中,子類是父類的派生類,它的實(shí)例化依賴于父類的實(shí)例化。所以它的任何一個(gè)構(gòu)造函數(shù)都必須要初始化父類,Java就是super關(guān)鍵字調(diào)用父類構(gòu)造方法,來完成這個(gè)操作。
有人會(huì)奇怪,那為什么在2.1.1的例子,父類沒有構(gòu)造方法,子類也沒有構(gòu)造方法,難道在某些情況下,實(shí)例的初始化并不依賴于構(gòu)造函數(shù)?
答案是,實(shí)例的初始化必須要構(gòu)造函數(shù)。2.2.1沒有構(gòu)造函數(shù)的原因是,在Java類定義中,如果開發(fā)者沒有顯示的定義構(gòu)造函數(shù),那么Java會(huì)隱式的為該類定義一個(gè)無參構(gòu)造函數(shù)。但是如果開發(fā)者自己定一個(gè)構(gòu)造函數(shù)(無論有參還是無參),那么Java就不會(huì)再為該類隱式的定義一個(gè)無參構(gòu)造函數(shù)了。
那么還原構(gòu)造函數(shù)后的代碼:
public class Parent { ... public Parent() { } ... } public class Child extends Parent { ... public Child() { } ... }
那么又有人有奇怪了,你不是說子類的實(shí)例化依賴于父類的實(shí)例化,那么在子類的構(gòu)造函數(shù)中應(yīng)該需要調(diào)用super來初始化父類不是嗎?
是的,在我們子類的構(gòu)造函數(shù)中,如果我們沒有顯式調(diào)用super來初始化父類的話,那么Java會(huì)隱式的調(diào)用super();來調(diào)用父類無參構(gòu)造函數(shù)并把它放在構(gòu)造函數(shù)的第一行。記住哦,Java只會(huì)隱式的調(diào)用無參構(gòu)造函數(shù),如果父類沒有無參構(gòu)造函數(shù),那么子類中就必須顯示的調(diào)用super關(guān)鍵字來調(diào)用已有的有參構(gòu)造函數(shù)來初始化父類。
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() {//如果沒有super來初始化父類,同樣也會(huì)報(bào)錯(cuò) // super();//編譯期報(bào)錯(cuò),因?yàn)楦割惒]有無參構(gòu)造函數(shù) super(15);//正確打開方式 } private void printParentName(){ System.out.println("爸爸的名字叫" + super.name); } private void parentStatus(){ super.sleeping(); } }
子類中的super為什么必須要放在第一行?因?yàn)樽宇惖膶?shí)例化依賴于父類的實(shí)例化,在構(gòu)建子類時(shí),必須要有父類實(shí)例,只能有了父類的實(shí)例,子類才能夠初始化自己。就好像人類世界里,都是要先有父親,再有孩子一樣。
附:super實(shí)際使用示例
下面來看看super關(guān)鍵字的實(shí)際用法。 在這里,Emp類繼承了Person類,所以Person的所有屬性都將默認(rèn)繼承到Emp。 要初始化所有的屬性,可使用子類的父類構(gòu)造函數(shù)。 這樣,我們重用了父類的構(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)鍵字指代父類對象,主要用于在子類中指定父類的方法和屬性,也用于在子類中初始化父類。子類的靜態(tài)方法中不能使用super關(guān)鍵字。
到此這篇關(guān)于Java基礎(chǔ)之super關(guān)鍵字的文章就介紹到這了,更多相關(guān)Java super關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Spring Boot使用JpaRepository刪除數(shù)據(jù)時(shí)的注意事項(xiàng)
這篇文章主要介紹了Spring Boot使用JpaRepository刪除數(shù)據(jù)時(shí)的注意事項(xiàng),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06在java8中使用流區(qū)分質(zhì)數(shù)與非質(zhì)數(shù)詳解
這篇文章主要介紹了在java8中使用流區(qū)分質(zhì)數(shù)與非質(zhì)數(shù)詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12詳解Java中ByteArray字節(jié)數(shù)組的輸入輸出流的用法
ByteArrayInputStream和ByteArrayOutputStream分別集成自InputStream和OutputStream這兩個(gè)輸入和輸出流,這里我們就來詳解Java中ByteArray字節(jié)數(shù)組的輸入輸出流的用法,需要的朋友可以參考下2016-06-06解決SpringMVC 返回Java8 時(shí)間JSON數(shù)據(jù)的格式化問題處理
本篇文章主要介紹了解決SpringMVC 返回Java8 時(shí)間JSON數(shù)據(jù)的格式化問題處理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02Java利用 Exchanger 實(shí)現(xiàn)游戲中交換裝備
JDK 1.5 開始 JUC 包下提供的 Exchanger 類可用于兩個(gè)線程之間交換信息。下面我們就來看看Java是如何利用Exchanger一行代碼實(shí)現(xiàn)游戲中交換裝備的2021-09-09