java 里的內部類
java里的內部類通常能幫我們隱藏一些具體實現,體現良好的封裝效果。
內部類又分幾種:
1.普通內部類
2.局部內部類
3.匿名內部類
4.靜態內部類
普通內部類
先(xian)來看第一種(zhong)普通(tong)的(de)內部類(lei),這種(zhong)內部類(lei)就非(fei)常簡單(dan)了,就是將一個(ge)類(lei)的(de)聲明放在另一個(ge)類(lei)的(de)內部
class Outer{
//外部類
class Inner{
//內部類
}
}
這樣的話就可以聲明出一個普通的內部類

但是在內部類(lei)(lei)聲明的(de)(de)同時,該內部類(lei)(lei)會追(zhui)蹤(zong)到外(wai)部類(lei)(lei)的(de)(de)引(yin)用(yong),因此,內部類(lei)(lei)可(ke)以(yi)訪問到外(wai)部類(lei)(lei)的(de)(de)所有(you)的(de)(de)域(yu)和方(fang)法,包括private聲明的(de)(de)域(yu)和方(fang)法,換個說法來說也(ye)就是外(wai)部類(lei)(lei)里(li)的(de)(de)所有(you)的(de)(de)域(yu)和方(fang)法對于內部類(lei)(lei)來說都是可(ke)見的(de)(de)。
class Outer{
//外部類
private int i = 1;
class Inner{
//內部類
public void func(){
System.out.println(i);
}
}
}
這樣的(de)寫法(fa)是(shi)不會有任何(he)的(de)編譯時報錯的(de)
這樣恰巧證明了內部類是可以訪問到外部類所有的域和方法
那么,我們怎樣去創建一個內部類的對象呢?
廢話不多(duo)說(shuo)我們直接代碼說(shuo)話
public class Main {
public static void main(String[] args){
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
}
}
由于 Inner是內(nei)嵌在Outer里(li)的(de)(de),所以(yi)我們必(bi)須(xu)(xu)要聲明整(zheng)個Outer才能加載inner的(de)(de)這塊內(nei)存(cun),因此我們必(bi)須(xu)(xu)先創建Outer的(de)(de)對(dui)象(xiang)(xiang),再來使(shi)用(yong)Outer的(de)(de)引(yin)(yin)用(yong)new出inner的(de)(de)對(dui)象(xiang)(xiang)。這樣(yang)的(de)(de)話我們就(jiu)持有inner對(dui)象(xiang)(xiang)的(de)(de)引(yin)(yin)用(yong)了
靜態內部類
普通內部類介紹完了再來看靜態內部類,這個內部類和普通內部類沒什么區別,區別只是多了一個static關鍵字,為表明它是靜態的,加上這個關鍵字以后,它不能持有外部類的引用了,并且不能訪問到外部類的非靜態方法和域。 我們將上面的代碼加做修改 ``` class Outer{ //外部類 private int i = 1; static class Inner{ //內部類 public void func(){ System.out.println(i); } } } ``` 我們把它聲明為static之后,會發現編譯器報了一個錯  不能訪問到非靜態的域。 這樣的情況出現,我們就更清晰明了了,因為我們會發現它和static修飾字段和方法的作用是差不多的。除此之外,它和普通的內部類就沒有什么區別了。 下面我們來看一下靜態內部類怎樣去創建一個對象 ``` public class Main { public static void main(String[] args){ Outer.Inner inner = new Outer.Inner(); } } ``` 由于靜態內部類是一塊獨立的靜態內存,因此我們可以直接這樣去聲明它,并且不用依靠外部類的對象局部內部類
所謂的局部內部類就是聲明在方法體里的內部類,或者聲明在某個作用域里的內部類 ``` class Outer{ //外部類 private int i = 1; public void func(){ class Inner{ public Inner innerFunc(){ System.out.println(i); return new Inner(); } } } } ``` 或者你也可以將類定義在隨意的一個作用域里,比如if語句 ``` class Outer{ //外部類 private int i = 1; public void func(){ if(true){ class Inner{ public Inner innerFunc(){ System.out.println(i); return new Inner(); } } } else{ // } } } ```匿名內部類
在講解這個之前,試問你們有沒有見過new 一個接口,相信大家已經見過很多次了吧,但是java里明確的規定接口是不能被創建對象的,但是下面這個例子卻能夠正常的運行 ``` public class Main { public static void main(String[] args){ Temp temp = new Temp(){ public void func(){ System.out.println("hello world"); } }; } }interface Temp{
void func();
}
然后我們調用func();
temp.func();
接下來我們可以明確的看到控制臺上打印出來的"hello world",那么這又是怎么回事呢,這就要涉及到我們要講解的匿名內部類
首先這根本不是我們看到的那樣new了接口,而是用了一個匿名的內部類去實現了這個接口,然后重寫了func方法,最后將整個內部類向上轉型為Temp,賦值給它的引用。
這樣的話,能夠輕松的幫助我們實現接口,但是有一個問題也接踵而來,那就是限制了代碼的復用。
