Java中的內(nèi)部類你了解嗎
成員內(nèi)部類
1.定義
成員內(nèi)部類是直接定義在類中,不加任何修飾符的(特指不加static修飾的)的內(nèi)部類,可以類比著成員變量來理解,如下面這個代碼段中的Inn類就是一個成員內(nèi)部類
public class Inner1 { private String o = "外部類屬性"; public class Inn{ private String i = "成員內(nèi)部類屬性"; } }
2.成員內(nèi)部類的使用規(guī)則
- 內(nèi)部類可以直接的訪問外部類的成員變量,但是因為內(nèi)部類也是一個類,所以外部類必須通過內(nèi)部類的對象才能訪問內(nèi)部類的成員變量
- 內(nèi)部類就相當(dāng)于外部類的成員變量,故而內(nèi)部類與外部類之間可以方便的相互訪問,包括privte權(quán)限修飾的屬性和方法
- 成員內(nèi)部類可以實現(xiàn)“曲線救國”,通過多個內(nèi)部類繼承別的類,變相的實現(xiàn)多繼承
//成員內(nèi)部類 public class Inner1 { // 外部類的私有屬性o private String o = "外部類屬性"; public class Inn{ // 內(nèi)部類的私有屬性i private String i = "成員內(nèi)部類屬性"; private void Itest(){ // 內(nèi)部類直接訪問外部類的屬性,包括私有屬性 System.out.println(o); } } public void Otest(){ // 外部類則要先創(chuàng)建內(nèi)部類的對象再訪問其成員變量,這里注意,也可以訪問其私有屬性 Inn in = new Inn(); in.Itest(); System.out.println(in.i); } public static void main(String[] args) { Inner1 i1 = new Inner1(); i1.Otest(); } }
3.成員內(nèi)部類對象的創(chuàng)建:
- 外部類的內(nèi)部創(chuàng)建:與正常類的對象創(chuàng)建方法一樣,
- 內(nèi)部類名稱 對象名 = new 類名()
public class Inner1 { private String str1 = "外部類"; // 外部類內(nèi)部創(chuàng)建內(nèi)部類對象 Inn i1 = new Inn(); private class Inn{ private String str2 = "內(nèi)部類"; } }
- 外部類的外部創(chuàng)建:成員內(nèi)部類就相當(dāng)于是外部類的一個特殊的成員變量,故而,我們知道,成員內(nèi)部類依賴于外部類的存在而存在,也就是說,必須先有外部類的對象才能創(chuàng)建成員內(nèi)部類的對象
- 外部類名稱.內(nèi)部類名稱 對象名 = new 外部類名稱().new 內(nèi)部類名稱()
- 當(dāng)前,在外部類的外部創(chuàng)建內(nèi)部類對象時,前提也需得內(nèi)部類對外部類的外部是可見的
如下圖, 內(nèi)部類為private,在外部類的外部無法創(chuàng)建該對象
修改內(nèi)部類訪問權(quán)限為public時正確創(chuàng)建 :
public class Inner1 { private String str1 = "外部類"; // 外部類內(nèi)部創(chuàng)建內(nèi)部類對象 Inn i1 = new Inn(); public class Inn{ private String str2 = "內(nèi)部類"; } } class Test{ // 外部類的外部創(chuàng)建外部類的內(nèi)部類對象 Inner1.Inn i2 = new Inner1().new Inn(); }
4.內(nèi)部類與靜態(tài)域
- 成員內(nèi)部類可以訪問外部類的靜態(tài)域,但是自己不能定義靜態(tài)變量(成員內(nèi)部類是依賴于外部類的,如果它自己能定義靜態(tài)變量,沒有外部對象也能訪問了,失去其意義)
- 外部類中的靜態(tài)方法也不能使用成員內(nèi)部類(相當(dāng)于在靜態(tài)變量中調(diào)用成員變量,是不可行的)。
- 為此,特別注意,main方法就是static方法,故而不能直接在外部類的main方法中創(chuàng)建內(nèi)部類對象,要借助外部類才能創(chuàng)建
public class Inner1 { private String str1 = "外部類"; // 外部類內(nèi)部創(chuàng)建內(nèi)部類對象 Inn i1 = new Inn(); public class Inn{ private String str2 = "內(nèi)部類"; } public static void main(String[] args) { // main中創(chuàng)建 Inner1.Inn inn = new Inner1().new Inn(); System.out.println(inn.str2); } }
靜態(tài)內(nèi)部類:
1.定義:
- 靜態(tài)內(nèi)部類也是定義在類中,但是與成員內(nèi)部類不同的是,它用static修飾,是靜態(tài)內(nèi)部類,可類比靜態(tài)變量進(jìn)行理解
- static修飾,所以它無需依賴外部類對象,我們可以把它看作一個普通類
public class Inner2 { private String str1 = new String("外部"); // 靜態(tài)內(nèi)部類 public static class Inn{ private String str2 = new String("靜態(tài)內(nèi)部"); } }
2.靜態(tài)內(nèi)部類的使用規(guī)則:
靜態(tài)內(nèi)部類不能直接訪問外部類的普通成員變量 (普通成員變量有對象才能訪問,所以static不能訪問普通的成員變量),當(dāng)然,可以通過new一個外部類的對象來達(dá)到訪問外部類成員變量的目的
public class Inner2 { private String str1 = new String("外部"); private static String str3 = new String("外部靜態(tài)屬性"); // 靜態(tài)內(nèi)部類 public static class Inn { private String str2 = new String("靜態(tài)內(nèi)部"); public void fun(){ // 靜態(tài)內(nèi)部類不能直接訪問外部類的普通成員變量 System.out.println(str1); // 但可以通過new一個外部類對象訪問 Inner2 i2 = new Inner2(); System.out.println(i2.str1); // static家族互通 System.out.println(str3); } } }
但是,靜態(tài)內(nèi)部類雖然不能直接訪問外部類的成員變量,但是是可以擁有自己的普通成員變量 的
3.靜態(tài)內(nèi)部類對象的創(chuàng)建
- 外部類內(nèi)部:和普通類的用法相同 ,且不同于成員內(nèi)部類,在靜態(tài)內(nèi)部類這里,外部類的靜態(tài)方法中是可以創(chuàng)建靜態(tài)內(nèi)部類的對象(static家族互訪),當(dāng)然,沒有對象都可以,那么,外部類的成員方法中也是可以創(chuàng)建靜態(tài)內(nèi)部類對象的
- 內(nèi)部類名稱 對象名 = new 類名()
public class Inner2 { private String str1 = new String("外部"); // 靜態(tài)內(nèi)部類 public static class Inn{ private String str2 = new String("靜態(tài)內(nèi)部"); } // 直接在類的內(nèi)部創(chuàng)建靜態(tài)內(nèi)部類的對象 Inn i = new Inn(); public static void main(String[] args) { // 外部類的靜態(tài)方法中創(chuàng)建使用靜態(tài)內(nèi)部類的對象 Inn inn = new Inn(); } }
外部類的外部:
外部類名稱.內(nèi)部類名稱 對象名 = new 外部類名稱. 內(nèi)部類名稱()
public class Inner2 { private String str1 = new String("外部"); // 靜態(tài)內(nèi)部類 public static class Inn { private String str2 = new String("靜態(tài)內(nèi)部"); } } class Test{ // 外部類的外部創(chuàng)建靜態(tài)內(nèi)部類的對象 Inner2.Inn i = new Inner2.Inn(); }
成員內(nèi)部類 VS 靜態(tài)內(nèi)部類
- 成員內(nèi)部類可以訪問外部類的成員域和靜態(tài)域,但是不能擁有自己的靜態(tài)域
- 靜態(tài)內(nèi)部類不可以直接訪問外部類的成員域,但可以擁有自己的成員域,另外,static家族互訪,隨意
方法內(nèi)部類:
1.定義:
直接定義在方法內(nèi)部,不允許使用任何修飾符修飾(包括訪問權(quán)限修飾符,static等),對外部完全隱藏,出了這個方法,這個類就沒有了,可以類比局部變量進(jìn)行理解
2.方法內(nèi)部類的使用規(guī)則:
除了無法定義static域外,和成員內(nèi)部類基本一樣,這里不再贅述
3.注意形參的使用
方法內(nèi)部類中若使用了方法的形參, 該形參為隱式的final聲明(JDK8之前,必須手動顯式定義為final ,但JDK8以后,直接隱式一定為final)
如下面這個例子:
public class Inner3 { public void fun(int num){ // 方法內(nèi)部類 class Inn{ public void test(){ // 將下面這行代碼注釋掉,num正常可作運算 // System.out.println(num); } } num ++; System.out.println(num); } public static void main(String[] args) { Inner3 i3 = new Inner3(); i3.fun(3); } }
但如果我們的方法內(nèi)部類使用了方法的形參,編譯報錯
匿名內(nèi)部類(函數(shù)式編程)
- 是方法內(nèi)部類的特殊版本,直接不寫類名稱
- 遵從方法內(nèi)部類的所有要求
- 默認(rèn)會繼承一個類或?qū)崿F(xiàn)一個接口,繼承類一般是繼承抽象類
- 通常是在傳參的過程中使用該類,可以簡化寫法
如之前我們寫的接口傳參:
public class Inner4 { public static void fun(MessageImpl m) { m.printMessage(); } public static void main(String[] args) { MessageImpl l = new MessageImpl(); fun(l); } } interface IMessage { void printMessage(); } class MessageImpl implements IMessage { public void printMessage() { System.out.println("aaa"); } }
使用匿名內(nèi)部類可以這樣寫:
public class Inner4 { public static void fun(IMessage m ){ m.printMessage(); } public static void main(String[] args) { // 匿名內(nèi)部類 fun(new IMessage() { @Override public void printMessage() { System.out.println("aaa"); } }); } } interface IMessage { void printMessage(); }
最后,重點掌握成員內(nèi)部類與靜態(tài)內(nèi)部類,以及二者使用區(qū)別。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
springboot如何將http轉(zhuǎn)https
這篇文章主要介紹了springboot如何將http轉(zhuǎn)https,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04解決mybatis-plus通用mapper調(diào)用報錯:Invalid bound statement
這篇文章主要介紹了解決mybatis-plus通用mapper調(diào)用報錯:Invalid bound statement的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09JAVA 開發(fā)之用靜態(tài)方法返回類名的實例詳解
這篇文章主要介紹了JAVA 開發(fā)之用靜態(tài)方法返回類名的實例詳解的相關(guān)資料,這里主要說明使用異常來得到類名,希望能幫助到大家,需要的朋友可以參考下2017-08-08