?? 11_inner_class_day06.txt
字號:
內部類:
封裝的一種
例子:鏈表中的節點.節點這個類定義再鏈表這個類的內部.并且可以把節點的訪問范圍定義成私有,那么只有再鏈表內部可以看到節點這個類.
實際開發中,有A B兩個類型,A類對象是寄生在B類對象內部的.
種類
成員式
成員內部類
定義在成員變量的位置的類.
靜態內部類
在類定義時把類聲明成靜態.
局部式
局部內部類
在方法內部定義的類.
匿名內部類
也在方法內部定義,但是不寫類的名字.
成員式
使用
public class OuterA{
private String name="hehe";
private static String name2="xixi";
public class InnerA{//成員內部類
public void m2(){
String name="heihei";
System.out.println("name="+name);
System.out.println("name="+OuterA.this.name);//訪問外部類的屬性
System.out.println("name2="+name2);
}
}
public static class InnerB{
public void m3(){
//System.out.println("name="+name);靜態內部類內部不能訪問非靜態成員.
System.out.println("name2="+name2);
}
}
}
public class InnerClassTest{
public static void main(String[] args){
OuterA out=new OuterA();
OuterA.InnerA inn//內部類型的訪問語法.可以把外部類當成內部類的一層包結構.
=out.new InnerA();//用外部類對象 . new 內部類對象.
OuterA.InnerB innb=new OuterA.InnerB();
}
}
成員內部類
和類里面的成員一樣.
我們把成員內部類當成外部類的一個成員,訪問成員是需要有外部類的對象.
訪問成員內部類需要外部類型,要想生成成員內部類對象就要先生成一個外部類對象.
靜態內部類
和類里面定義的靜態成員一樣,對于靜態成員的訪問,可以在沒有生成對象之前訪問靜態內部類.
修飾附 static final abstract
成員式內部類 y y y
局部式內部類 n y不繼承 y
訪問限制修飾符 public protected default private
頂層類 y n y n
成員式內部類 y y y y
局部式內部類 n n n n//局部變量沒有訪問權限
作用:
讓一個類訪問另外一個類的私有屬性可以使用內部類.
成員內部類本質
System.out.println("name="+name);
System.out.println("name="+this.name);//這是錯誤的.
this.name表示訪問的內部類自己的,上面一條語句是訪問外部類的name.
如果內部類里面沒有name屬性.直接寫就可以訪問到外部類的name
如果內部類里面也有name屬性.那么需要寫成 外部類.this.name 訪問外部類的屬性.
外部類.this 表示外部類當前對象.就是創建內部類對象的那個外部類對象.
每個內部類對象都有一個內部類對象和它關聯.
通過以上特點分析得到:
編譯器會為成員內部類定義一個屬性
//private OuterA out;
public InnerA(/*OuterA out*/){
//this.out=out;
}
實際上編譯器會為每個內部創建一個私有的外部類對象的引用.
如果自己寫了構造方法,那么編譯器會把構造方法改成:
public InnerA(/*OuterA out,*/String name){
//this.out=out
......;
}
在使用的時候OuterA.this編譯器會把這個代碼替換成 InnerA的屬性out.
在創建內部類對象的時候編譯器會該程
OuterA.InnerA inn=out.new InnerA();
//OuterA.InnerA inn=new InnerA(out);
描述:
對于任何一個成員內部類,系統都會個它加上一個私有的外部類的引用,并且在內部類的所有構造方法的參數列表里面加上一個外部類的變量.并且在方法內部默認的把外部類屬性賦值給私有的屬性.這些都是默認的.
所以內部類也是一個徹頭徹尾的編譯器行為
所以最終在編譯之后,內部類和外部類都是一樣的.并且.class文件也是兩分.
所有的語法都是由編譯器來保證的.它的語法都是可以轉換成我們熟悉的語法.
成員內部類對于外部類對象綁定起來.
靜態內部類
可以認為和外部類沒有太大的關系,只是一種寄居的關系.
可以只用外部類對象直接的訪問內部類對象.
局部式:
public class OuterB{
public MyInter m1(){
class InnerC implements MyInter{
public void m4(){
System.out.println("InnerC.m4");
}
public void m3(){
System.out.println("InnerC.m3");
}
}
//return new InnerC;
return new MyInter(){//生成一個MyInter的實現類.
public void m4(){
System.out.println("InnerC.m4");
}
public void m3(){
System.out.println("InnerC.m3");
}
};
}
public void m2(){
//InnerC inn;
}
}
interface MyInter{
void m3();
void m4();
}
public class InnerClassTest{
public static void main(String[] args){
OuterB outb=new OuterB();
Object o=outb.m1;//雖然得到了InnerC的對象但是依然無法使用,多態的第一條定理.
}
}
局部內部類.
局部內部類只在定義它的方法體里面有效.
所以.相對來講沒有辦法在方法外部得到局部內部類的對象.
即使在本類內部其他方法里面都沒有辦法使用局部內部類.
外太空沒有人類的定義,不知道由什么樣的屬性和方法.
局部內部類式定義在方體內部的類,所以這個類只在方法體內部有效,如果希望能在外部使用那么需要:
1.在局部內部類的方法里面返回局部內部類.
但是只能用Object來接收.
2.后來在外部定義了一個接口,讓局部內部類實現這個接口.
通過接口的引用就可以調用接口定義的方法.
這就是接口的回調.
怎么樣讓局部內部類的定義變得有意義.
這時發現其實內部類的名子沒有意義,外部的人根本不關心.
這就引出了匿名內部類.
把生成對象和定義類的兩個工作合二為一.
內部類隱含的一些特征.
局部內部類
局部內部類只能訪問方法中final的局部變量。
語句再局部類內部訪問方法中的局部變量這是一個錯誤。
再方法內的類的定義再調用方法的時候是不會指定類的定義里面的代碼的。如果把局部內部類的對象,那么方法內部的局部變量的空間就被釋放了,在類的內部對局部變量的訪問也就是錯誤的。
細節,如果在局部內部類里面訪問方法中的局部變量,編譯器會在內部類里面多加入一個屬性,這個屬性和局部變量的定義完全相同: private final int b=20;
變量為什么不能拷貝,因為局部變量是一個瞬態的概念,那么希望能訪問到這個值,如果在局部內部類里面再去修改這個變量,但是這個變量已經不存在了。那么這個修改是不可行的。流星和照片
內部類的意義:
1.更小層次的封裝。
比包結構更小層次的封裝,在一個類的內部聲明的類,可以給內部的這個類設置訪問權限。
2.內部類可以訪問外部類的私有成員。
3.匿名內部類可以方便的實現運行時的接口回調。
如果有一個接口,希望生成接口的實現類,并且得到實現類的對象,那么使用匿名內部類的方式是最方便的。而且這種接口回調是在運行時的特征。
它還經常的被應用在事件編程中。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -