概述:
內部類,顧名思義,就是在一個類中再定義一個類,再次定義的那個類就稱爲內部類。這個就很容易理解啦。內部類可分爲成員內部類、局部內部類、匿名內部類以及靜態內部類。使用內部類可以節省編譯後產生的字節碼(.class)文件的大小,而且在實現事件監聽時,採用內部類很容易實現。但是,使用內部類的最大問題是會使結構不清晰,所以在程序開發時,不用刻意的去追求使用內部類。
目錄
一、成員內部類
在一個類中使用內部類,可以在內部類中直接存取其所在外部類的私有成員變量。在內部類中可以使用外部類的所有成員變量和成員方法,即使成員被修飾爲 private 。
內部類的對象實例化操作必須在外部類或外部類的非靜態方法中實現。
外部類不可以直接訪問內部類成員變量。
內部類的實例一定要綁定在外部類對象上,如果從外部類中初始化一個內部類對象,那麼內部類對象就會綁定在外部類對象上。
如果在外部類和非靜態方法之外實例化內部類對象,需要使用(外部類.內部類)的形式指定該對象。
內部類對象與外部類對象關係非常緊密,內外可以交互使用彼此類中定義的變量。
案例:創建一個TestOuterClass外部類,在類中定義TestInnerClass內部類。我列出來很多種情況,註釋掉的是不可用的
package cn.cou.pack;
public class TestOuterClass { //外部類
TestInnerClass in = new TestInnerClass();//在外部類中實例化內部類對象
//in.engine();//不可用
public void ccar()
{
System.out.println("滴滴滴滴");
//sname = "sn";//外部類不可以直接訪問內部類成員變量
in.sname="sn";
in.age = 3;//外部類可以訪問內部類私有成員變量
in.engine();//在外部類方法中調用內部類方法
}
private void go() { //外部類私有方法
System.out.println("出發");
}
private String name;//外部類私有成員變量
class TestInnerClass{ //內部類
String sname ;
private int age;
public void engine()
{
System.out.println(".......");
}
void outen() {
go(); //內部類的方法中可以使用外部類的所有成員變量和方法
System.out.println("name="+name);
}
}
public static void main(String[] agrs) {
TestOuterClass out = new TestOuterClass();//外部類實例化對象
out.name = "car";
out.ccar();
out.go();
out.in.age=3;
out.in.engine();
out.in.sname = "carmotor";
System.out.println("out.name ="+out.name+"\n"+"out.in.sname ="+out.in.sname);
//out.sname = "carmo";//外部類不能直接訪問內部類成員
//out.in.age; //不能使用內部類私有變量
TestOuterClass.TestInnerClass in1 = out.new TestInnerClass();//在主方法中實例化內部類對象
in1.sname = "motor";
in1.engine();
//in1.age;
//in1.ccar();
//in1.name;
//TestInnerClass in2 = new TestInnerClass();
//TestOuterClass.TestInnerClass in2 = out.ccar();
}
}
成員內部類向上轉型爲接口:
如果將一個private修飾的內部類向上轉型爲其父類對象,或者直接向上轉型爲一個接口,在程序中就可以完全隱藏內部類的具體實現過程。可以在外部提供一個接口,在接口中聲明一個方法,如果在實現該接口的內部類中實現該接口的方法,那麼就可以定義多個內部類用不同的方式實現接口中的一個方法,而一般的類是不能多次實現接口中同一個方法的,這個技巧通常用在Swing編程中。
案例:
package cn.cou.pack;
public interface OutInterface {
public void OutIF();
}
package cn.cou.pack;
public class InnerInterface {
public static void main(String[] agrs) {
OuterClass out = new OuterClass();//實例化OuterClass對象
OutInterface outinter = out.doit();//調用doit方法,返回一個OuterClass接口
outinter.OutIF();//調用OutIF()方法
}
}
class OuterClass{
private class InnerClass implements OutInterface{ //定義內部類實現OutInterface接口
InnerClass(String s){ //內部類構造方法
System.out.println(s);
}
public void OutIF() { //實現接口中的OutIF()方法
System.out.println("訪問內部類中的OutIF()方法");
}
}
public OutInterface doit() { //定義一個方法,返回值值類型爲OutInterface接口
return new InnerClass("訪問內部類構造方法");
}
}
二、局部內部類
內部類不僅可以在類中進行定義,也可以在類的局部位置定義,比如說在類的方法或任意的作用域中均可定義內部類。當內部類被定義在局部時不可以再被成員修飾符修飾,仍然可以訪問外部類中的成員,因爲其還持有外部類的引用。但是不可以訪問它所在局部中的變量,如果需要在局部內部類中使用局部變量,該局部變量需要被設置爲final類型,即在方法中定義的局部內部類只能訪問方法中final類型的局部變量。由於該局部變量內設置爲final,所以不能在內部類中改變該局部變量的值。
案例:
package cn.cou.pack;
public class TestTopoClass {
public static void main(String[] args) {
TestTopoClass topo = new TestTopoClass();
OutInterface outerface = topo.doit(null);
outerface.OutIF();
}
public OutInterface doit(final String x) {
class TopointerClass implements OutInterface{
TopointerClass(String s){
s=x;
System.out.println(s);
}
public void OutIF()
{
System.out.println("OutIF方法");
}
}
return new TopointerClass("doit");
}
}
三、匿名內部類
匿名內部類就是沒有名字的內部類,就是內部類的簡寫格式。匿名內部類就是一個匿名子類對象,可以理解爲帶內容的對象。匿名內部類沒有構造方法,不能定義靜態成員,不能用private、public、protected、static、final、abstract等修飾,只可以創建一個匿名類實例。
匿名內部類格式:
new 父類或者接口(){
//定義子類的內容
}
四、靜態內部類
在內部類前添加修飾符static,那麼這個內部類就變成靜態內部類,一個靜態內部類可以聲明靜態成員, 在非靜態內部類中不可以聲明靜態成員。靜態內部類最大的特點就是不能使用外部類的非靜態成員,所以靜態內部類在開發中比較少見。