Java學習——內部類的定義與使用
內部類
定義:在一個類的內部進行其他類結構的巢狀。
先寫一個內部類
class Outer{ private String msg = "Hello World"; //=============內部類================== class Inner{ public void print(){ System.out.println(Outer.this.msg);//呼叫Outer的private屬性 } } //=============內部類================== //產生一個內部類物件並呼叫內部類的print方法 public void fun(){ new Inner().print(); } } public class Test{ public static void main(String[] args) { Outer ou = new Outer(); ou.fun(); } }
引入內部類後,程式的結構有些混亂。雖然內部類破壞了程式的結構,但是從另一方面來講,內部類可以方便的操作外部類的私有訪問。
如果這個操作不用內部類來寫,會是什麼情況呢?
class Outer{ private String msg = "Hello World"; public String getMsg(){ return msg; } public void fun(){ new Inner().print(this); } } class Inner{ public void print(Outer ou){ System.out.println(ou.getMsg()); } } public class Test{ public static void main(String[] args) { Outer ou = new Outer(); ou.fun(); } }
可見程式碼比上面的複雜了一些,要寫get函式獲取outer類的私有屬性。
內部類存在的意義:
1.內部類與外部類可以互相訪問彼此的私有域(最大優點)
2.內部類可以實現Java的單繼承侷限
3.內部類可以對同一包中的其他類隱藏起來,僅供外部類使用(保護性)
缺點:結構複雜
內部類分類
1.成員內部類——對比成員方法理解
a.成員內部類不能存在任何static變數或方法,但可以訪問外部類的靜態域;(成員內部類需要依附外部類的建立而建立,而static變數或方法與物件無關,即便沒有外部類也可以建立static變數或方法,這就與前面矛盾)
b.成員內部類需要依附外部類——new Outter().new Inner();先建立外部類再建立內部類;
c.內部類可以使用private封裝,表示私有內部類,該內部類僅供外部類使用(如HaspMap中的Entry內部類,ArrayList中的Node內部類)
2.靜態內部類-用static修飾——對比靜態方法理解
a.靜態內部類的建立不需要外部類,可以直接建立
b.靜態內部類不可以訪問外部類的任何非static域,但可以存在成員變數
3.方法內部類
class Outer{
private String msg = "Hello World";
public void fun(){
class Inner{
public void print(){
System.out.println(Outer.this.msg);//呼叫Outer的private屬性
}
}
new Inner().print();;
}
}
public class Test{
public static void main(String[] args) {
Outer ou = new Outer();
ou.fun();
}
}
1.方法內部類不能使用任何訪問許可權修飾符(如public、private)
2.方法內部類對外(方法外)完全隱藏,除了該方法可以訪問它之外,其餘地方均不能訪問
3.方法內部類要想使用方法形參,該形參必須使用final宣告(jdk8變為隱式final宣告)
4.匿名內部類——方法內部類的特殊版本——lambda表示式的第一步
1.沒有訪問許可權修飾符
2.匿名內部類必須繼承一個抽象類或者實現一個介面
3.匿名內部類沒有構造方法,因為它沒有類名
interface Iif{
public void display();
}
class Test{
public static void main(String[] args) {
new Iif(){
@Override
public void display(){
System.out.println("匿名內部類");
}
}.display();
}
}
建立內部類
建立內部類的語法(在外部類的外部)
建立非靜態內部類
外部類.內部類 內部類引用 = new 外部類().new 內部類();
Outer.Inner in = new Outter().new Inner();
之所以要先進行外部類物件的例項化,因為此時外部類存在普通屬性,這些屬性必須進行例項化後才能訪問。
如果說現在一個內部類只想被外部類使用,即:不希望直接產生內部類的例項化物件,可以使用private定義。
在進行屬性訪問時,都需要加上this關鍵字。所以如果想在內部類中明確的使用this,那麼語法形式如下:外部類.this.屬性
建立靜態內部類
外部類.內部類 內部類引用 = new 外部類.內部類();
Outer.Inner in = new Outer.Inner();
內部類與外部類的關係
1.對非靜態內部類而言,內部類的建立需要依賴外部類的例項化物件,在沒有外部類物件之前是無法建立內部類的。
2.內部類是一個相對獨立的個體,與外部類也不是繼承關係。
3.內部類可以直接訪問外部類的元素(包含私有域),但是外部類不可以直接訪問內部類元素,需要通過內部類的引用間接訪問。