Java關(guān)鍵字super超詳細解釋
前言(廢話文學)
又是看了一大堆文字介紹,非常系統(tǒng)和官方,理解要費半天勁,所以總結(jié)一下super它到底有啥用,還有代碼演示也會放出來,這里使用的IDE為idea
前言(定義)
還是先官方一下
在java中,super表示超類(就是我們俗稱的父類),當子類需要引用父類的字段時,我們就可以使用super.FieldName.
因此,本文就將從構(gòu)造函數(shù),公有成員函數(shù),公有成員變量來分別演示super的作用,因為private私有成員是只允許自己使用的,所以這里也可以看出,super在繼承關(guān)系中,對公有字段起作用。
super()之構(gòu)造方法
如果父類(超類)沒有默認的構(gòu)造方法,子類就必須顯式調(diào)用super(),并且必須使用父類中的某個構(gòu)造方法的參數(shù)。
什么意思呢?
就是有一個父類Parent,子類Son,如果我們在Parent中定義了構(gòu)造函數(shù),那么在繼承父類的子類中就必須書寫父類的構(gòu)造函數(shù)。那么此時就需要將super()寫在子類構(gòu)造方法中。
如果父類中沒有定義構(gòu)造方法,那么編譯器會默認是public Parent(){}就是空的,此時在子類中不書寫super也不會報錯,因為編譯器默認生成子類構(gòu)造方法為空,super()就默認是隱藏的。
就是構(gòu)造函數(shù)必須有super(),(開個玩笑:你說那我看到的有的咋沒有,不是沒有,只是只有聰明人能看見嘿嘿嘿。)如果子類中沒有super(),那是因為編譯器替你干了這個活,它隱藏了super()這個默認的無參構(gòu)造方法,算是隱式調(diào)用。
注意顯式二字。
來了來了,代碼示例它來了
父類
public class Parent { //public Parent(){}//可以不寫,編譯器會默認是它,空的 // 為了查看效果,我們把父類無參構(gòu)造函數(shù)里加個輸出 public Parent(){ System.out.println("This is Parent!"); } }
子類
public class Son extends Parent{ public Son(){//此時不寫super也不會報錯,因為編譯器默認是有super(),只不過隱藏了。 System.out.println("This is son!"); } }
MyMain.java
public class MyMain { public static void main(String[] args){ Son son = new Son(); } }
來,讓我們看看效果,會發(fā)現(xiàn)父類構(gòu)造方法也執(zhí)行了。所以說super()意思就是調(diào)用父類的方法,往往我們通過傳參的方式來達到我們所先要的結(jié)果
現(xiàn)在修改父類代碼如下
public class Parent { public Parent(String name,int id){ System.out.println(name+" "+id); } }
子類代碼如下
public class Son extends Parent{ public Son(String name,int id){ System.out.println("This is son!"); } }
MyMain類代碼如下
public class MyMain { public static void main(String[] args){ String name ="Bob"; int id=12; Son son = new Son(name,id); } }
當當當,報錯了,為啥,你沒寫super,因為默認隱藏super是super(),它沒有傳入任何參數(shù),就導致子類在繼承父類時,父類構(gòu)造器就無法應用到子類中。
java: 無法將類 Parent中的構(gòu)造器 Parent應用到給定類型;
修改子類代碼如下,其它不變,發(fā)現(xiàn)可以運行了,因為傳入了String參數(shù)和int參數(shù),與父類一致,所以super()表示子類使用父類構(gòu)造函數(shù),(就是子類重載了父類函數(shù),因為函數(shù)名和參數(shù)都必須相同),同時它也可以自己在構(gòu)造函數(shù)中添加其它邏輯:
public class Son extends Parent{ public Son(String name,int id){ super(name, id); System.out.println("This is son!"); } }
super()之成員函數(shù)
對于可繼承的成員函數(shù),如果子類在重寫父類的方法同時想要調(diào)用(實現(xiàn))與父類相同的方法,那么就用super.func(obj,obj,…)。與構(gòu)造函數(shù)不同的是,super.func()可以不用放在函數(shù)一開始的位置,而構(gòu)造方法的super()必須放在函數(shù)體中最前面的位置。
來了來了,代碼示例它來了
父類
public class Parent { private String name="Pang pang"; private int id=12; private String selfIntro="This is a fat parent"; public Parent(){} public void getName() { System.out.println(name); } public void getId(){ System.out.println(id); } public void getSelfIntro() { System.out.println(selfIntro); } }
子類
public class Son extends Parent{ private static String sonIntro="This is Feifei's child"; public Son(){System.out.println("This is Son:");} @Override public void getSelfIntro() { System.out.println(sonIntro); System.out.println("I want to see my parents' introduction: "); super.getSelfIntro();//可寫可不寫,只是看子類想不想調(diào)用它,它可以放在任何想調(diào)用的位置,返回的是父類的介紹 //如果子類想調(diào)用卻不寫super的話就會報錯 } }
主類
public class MyMain { public static void main(String[] args){ //從子類讀取信息 Son son = new Son(); son.getSelfIntro(); } }
結(jié)果展示
看到這,你一定想問,那要是一個有參數(shù)的成員函數(shù)咋個整呢,是啊,咋個整呢。其實你會發(fā)現(xiàn),需要傳參的一般情況下不會再調(diào)用super,因為子類優(yōu)先原則會覆蓋掉父類的數(shù)據(jù),比如下面來演示一下。當然有的參數(shù)不影響的情況下,想要調(diào)用父類的含參成員函數(shù)還是可以調(diào)用super的
父類
public class Parent { private String name; private int id; public Parent(){} public void setInfo(String name,int id){ this.name=name; this.id=id; } public void getInfo(){ System.out.println(name+" "+id); } }
子類
public class Son extends Parent{ private String name; private int id; public Son(){} @Override public void setInfo(String name,int id){ super.setInfo(name,id);//將值傳遞給父類 this.name=name; this.id=id; } @Override public void getInfo(){//打印信息 System.out.println("This is parents' information:"); super.getInfo(); System.out.println("This is son's information: "); System.out.println(name+" "+id); } }
主類
public class MyMain { public static void main(String[] args){ //由于子類優(yōu)先原則,會將所有的值由子類傳遞給父類,順便演示一下子類優(yōu)先原則 //設置父類信息 Parent parent=new Parent(); String pName="Pang pang"; int pId = 11; parent.setInfo(pName,pId); System.out.println("This is first parent:"); parent.getInfo();//打印出來看看,此時還是很正常的父類的值 //設置子類信息,會發(fā)現(xiàn)父類信息失效了 Son son = new Son(); String sName = "Fei fei"; int sId = 15; son.setInfo(sName,sId); son.getInfo(); } }
super()之成員變量
通過super.變量名就可以在子類中訪問父類的成員變量,但是只有protected和public的成員變量可以被訪問,而private的變量子類是訪問不到的。
父類
public class Parent { private String inf1 = "Parent: stupid!"; protected String inf2 = "Parent: Kids!"; public String inf3 = "Parent: eat!"; }
子類
public class Son extends Parent{ private String inf1; protected String inf2; public String inf3; public Son(){} public void setInfo(String inf1,String inf2,String inf3){ this.inf1=inf1; this.inf2=inf2; this.inf3=inf3; } public void getInfo(){//打印信息 System.out.println("This is son's information: "); System.out.println(inf1); System.out.println(inf2); System.out.println(inf3); System.out.println("This is parents' information:"); //System.out.println(super.inf1); System.out.println(super.inf2); System.out.println(super.inf3); } }
主類
public class MyMain { public static void main(String[] args){ //設置子類信息 Son son = new Son(); String ss1 = "Son: mom!"; String ss2 = "SOn: sorry!"; String ss3 = "Son: play!"; son.setInfo(ss1,ss2,ss3); son.getInfo(); } }
運行結(jié)果
如果調(diào)用了private變量時會報錯的,如下圖
總結(jié)
到此這篇關(guān)于Java關(guān)鍵字super超詳細解釋的文章就介紹到這了,更多相關(guān)Java關(guān)鍵字super內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Security攔截器引起Java CORS跨域失敗的問題及解決
這篇文章主要介紹了Spring Security攔截器引起Java CORS跨域失敗的問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07舉例解析Java多線程編程中需要注意的一些關(guān)鍵點
這篇文章主要介紹了Java多線程編程中需要注意的一些關(guān)鍵點,包括ThreadLocal變量與原子更新等一些深層次的內(nèi)容,需要的朋友可以參考下2015-11-11Java中關(guān)于ThreadLocal的隱式引用詳解
這篇文章主要介紹了Java中關(guān)于ThreadLocal的隱式引用,從線程的角度看,每個線程都保持一個對其線程局部變量副本的隱式引用,只要線程是活動的,ThreadLocal實例就是可訪問的,下面我們來具體看看2024-03-03Java分析Lambda表達式Stream流合并分組內(nèi)對象數(shù)據(jù)合并
Lambda表達式,基于Lambda所帶來的函數(shù)式編程,又引入了一個全新的Stream概念,用于解決集合類庫既有的弊端,Lambda 允許把函數(shù)作為一個方法的參數(shù)(函數(shù)作為參數(shù)傳遞進方法中)。使用 Lambda 表達式可以使代碼變的更加簡潔緊湊2022-12-12