Java中的內(nèi)部類你了解嗎
成員內(nèi)部類
1.定義
成員內(nèi)部類是直接定義在類中,不加任何修飾符的(特指不加static修飾的)的內(nèi)部類,可以類比著成員變量來理解,如下面這個(gè)代碼段中的Inn類就是一個(gè)成員內(nèi)部類
public class Inner1 {
private String o = "外部類屬性";
public class Inn{
private String i = "成員內(nèi)部類屬性";
}
}2.成員內(nèi)部類的使用規(guī)則
- 內(nèi)部類可以直接的訪問外部類的成員變量,但是因?yàn)閮?nèi)部類也是一個(gè)類,所以外部類必須通過內(nèi)部類的對(duì)象才能訪問內(nèi)部類的成員變量
- 內(nèi)部類就相當(dāng)于外部類的成員變量,故而內(nèi)部類與外部類之間可以方便的相互訪問,包括privte權(quán)限修飾的屬性和方法
- 成員內(nèi)部類可以實(shí)現(xiàn)“曲線救國”,通過多個(gè)內(nèi)部類繼承別的類,變相的實(shí)現(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)部類的對(duì)象再訪問其成員變量,這里注意,也可以訪問其私有屬性
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)部類對(duì)象的創(chuàng)建:
- 外部類的內(nèi)部創(chuàng)建:與正常類的對(duì)象創(chuàng)建方法一樣,
- 內(nèi)部類名稱 對(duì)象名 = new 類名()
public class Inner1 {
private String str1 = "外部類";
// 外部類內(nèi)部創(chuàng)建內(nèi)部類對(duì)象
Inn i1 = new Inn();
private class Inn{
private String str2 = "內(nèi)部類";
}
}- 外部類的外部創(chuàng)建:成員內(nèi)部類就相當(dāng)于是外部類的一個(gè)特殊的成員變量,故而,我們知道,成員內(nèi)部類依賴于外部類的存在而存在,也就是說,必須先有外部類的對(duì)象才能創(chuàng)建成員內(nèi)部類的對(duì)象
- 外部類名稱.內(nèi)部類名稱 對(duì)象名 = new 外部類名稱().new 內(nèi)部類名稱()
- 當(dāng)前,在外部類的外部創(chuàng)建內(nèi)部類對(duì)象時(shí),前提也需得內(nèi)部類對(duì)外部類的外部是可見的
如下圖, 內(nèi)部類為private,在外部類的外部無法創(chuàng)建該對(duì)象

修改內(nèi)部類訪問權(quán)限為public時(shí)正確創(chuàng)建 :
public class Inner1 {
private String str1 = "外部類";
// 外部類內(nèi)部創(chuàng)建內(nèi)部類對(duì)象
Inn i1 = new Inn();
public class Inn{
private String str2 = "內(nèi)部類";
}
}
class Test{
// 外部類的外部創(chuàng)建外部類的內(nèi)部類對(duì)象
Inner1.Inn i2 = new Inner1().new Inn();
}4.內(nèi)部類與靜態(tài)域
- 成員內(nèi)部類可以訪問外部類的靜態(tài)域,但是自己不能定義靜態(tài)變量(成員內(nèi)部類是依賴于外部類的,如果它自己能定義靜態(tài)變量,沒有外部對(duì)象也能訪問了,失去其意義)
- 外部類中的靜態(tài)方法也不能使用成員內(nèi)部類(相當(dāng)于在靜態(tài)變量中調(diào)用成員變量,是不可行的)。
- 為此,特別注意,main方法就是static方法,故而不能直接在外部類的main方法中創(chuàng)建內(nèi)部類對(duì)象,要借助外部類才能創(chuàng)建
public class Inner1 {
private String str1 = "外部類";
// 外部類內(nèi)部創(chuàng)建內(nèi)部類對(duì)象
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修飾,所以它無需依賴外部類對(duì)象,我們可以把它看作一個(gè)普通類
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)部類不能直接訪問外部類的普通成員變量 (普通成員變量有對(duì)象才能訪問,所以static不能訪問普通的成員變量),當(dāng)然,可以通過new一個(gè)外部類的對(duì)象來達(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一個(gè)外部類對(duì)象訪問
Inner2 i2 = new Inner2();
System.out.println(i2.str1);
// static家族互通
System.out.println(str3);
}
}
}但是,靜態(tài)內(nèi)部類雖然不能直接訪問外部類的成員變量,但是是可以擁有自己的普通成員變量 的
3.靜態(tài)內(nèi)部類對(duì)象的創(chuàng)建
- 外部類內(nèi)部:和普通類的用法相同 ,且不同于成員內(nèi)部類,在靜態(tài)內(nèi)部類這里,外部類的靜態(tài)方法中是可以創(chuàng)建靜態(tài)內(nèi)部類的對(duì)象(static家族互訪),當(dāng)然,沒有對(duì)象都可以,那么,外部類的成員方法中也是可以創(chuàng)建靜態(tài)內(nèi)部類對(duì)象的
- 內(nèi)部類名稱 對(duì)象名 = 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)部類的對(duì)象
Inn i = new Inn();
public static void main(String[] args) {
// 外部類的靜態(tài)方法中創(chuàng)建使用靜態(tài)內(nèi)部類的對(duì)象
Inn inn = new Inn();
}
}外部類的外部:
外部類名稱.內(nèi)部類名稱 對(duì)象名 = 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)部類的對(duì)象
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等),對(duì)外部完全隱藏,出了這個(gè)方法,這個(gè)類就沒有了,可以類比局部變量進(jìn)行理解
2.方法內(nèi)部類的使用規(guī)則:
除了無法定義static域外,和成員內(nèi)部類基本一樣,這里不再贅述
3.注意形參的使用
方法內(nèi)部類中若使用了方法的形參, 該形參為隱式的final聲明(JDK8之前,必須手動(dòng)顯式定義為final ,但JDK8以后,直接隱式一定為final)
如下面這個(gè)例子:
public class Inner3 {
public void fun(int num){
// 方法內(nèi)部類
class Inn{
public void test(){
// 將下面這行代碼注釋掉,num正??勺鬟\(yùn)算
// System.out.println(num);
}
}
num ++;
System.out.println(num);
}
public static void main(String[] args) {
Inner3 i3 = new Inner3();
i3.fun(3);
}
}但如果我們的方法內(nèi)部類使用了方法的形參,編譯報(bào)錯(cuò)


匿名內(nèi)部類(函數(shù)式編程)
- 是方法內(nèi)部類的特殊版本,直接不寫類名稱
- 遵從方法內(nèi)部類的所有要求
- 默認(rèn)會(huì)繼承一個(gè)類或?qū)崿F(xiàn)一個(gè)接口,繼承類一般是繼承抽象類
- 通常是在傳參的過程中使用該類,可以簡化寫法
如之前我們寫的接口傳參:
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();
}最后,重點(diǎn)掌握成員內(nèi)部類與靜態(tài)內(nèi)部類,以及二者使用區(qū)別。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
MyBatis查詢時(shí)屬性名和字段名不一致問題的解決方法
這篇文章主要給大家介紹了關(guān)于MyBatis查詢時(shí)屬性名和字段名不一致問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
一段眼睛跟著鼠標(biāo)轉(zhuǎn)動(dòng)的跟蹤眼代碼
java實(shí)現(xiàn)的眼睛跟著鼠標(biāo)轉(zhuǎn)動(dòng)的跟蹤眼代碼2008-10-10
java統(tǒng)計(jì)漢字字?jǐn)?shù)的方法示例
這篇文章主要介紹了java統(tǒng)計(jì)漢字字?jǐn)?shù)的方法,結(jié)合實(shí)例形式分析了java正則判定、字符串遍歷及統(tǒng)計(jì)相關(guān)操作技巧,需要的朋友可以參考下2017-05-05
Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之時(shí)間復(fù)雜度與空間復(fù)雜度
對(duì)于一個(gè)算法,其時(shí)間復(fù)雜度和空間復(fù)雜度往往是相互影響的,當(dāng)追求一個(gè)較好的時(shí)間復(fù)雜度時(shí),可能會(huì)使空間復(fù)雜度的性能變差,即可能導(dǎo)致占用較多的存儲(chǔ)空間,這篇文章主要給大家介紹了關(guān)于Java時(shí)間復(fù)雜度、空間復(fù)雜度的相關(guān)資料,需要的朋友可以參考下2022-02-02
一文帶你看懂Android動(dòng)畫的實(shí)現(xiàn)原理
動(dòng)畫是 Android 應(yīng)用程序中重要的交互特性,ndroid 提供了多種動(dòng)畫效果,包括平移、縮放、旋轉(zhuǎn)和透明度等,它們可以通過代碼或 XML 來實(shí)現(xiàn),本文將介紹 Android 動(dòng)畫的原理和實(shí)現(xiàn)方法,并提供一些示例,需要的朋友可以參考下2023-07-07
Java實(shí)現(xiàn)企業(yè)員工管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)企業(yè)員工管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02

