內部類的定義與使用
阿新 • • 發佈:2018-12-09
基本概念:就是在一個類內部進行其他類結構巢狀操作。
內部類的優點
- 內部類與外部類可以方便地訪問彼此的私有域(包含私有方法、私有屬性)。
eg:
class Outer{ private String msg = "Hello World"; //內部類 //-------------------------------- class Inner{ public void print(){ System.out.println(msg); } } //-------------------------------- public void fun(){ Inner in = new Inner(); in.print(); } } public class InnerClass{ public static void main(String[] args){ Outer out = new Outer(); out.fun(); } }
- 內部類是另外一種封裝(保護性),對外部其他類隱藏。
- 外部類可以實現Java單繼承的侷限。
eg:
class A{ private String name = "A的私有域"; public String getName(){ return name; } } class B{ private int age = 20; public int getAge(){ return age; } } class Outter{ private class InnerClassA extends A{ public String name(){ return super.getName(); } } private class InnerClassB extends B{ public int age(){ return super.getAge(); } } public int age(){ return new InnerClassB().age(); } public String name(){ return new InnerClassA().name(); } } public class InnerToExtends{ public static void main(String[] args){ Outter out = new Outter(); System.out.println(out.name()); System.out.println(out.age()); } }
缺點:
結構複雜
內部類與外部類的關係
- 對於非靜態內部類,內部類的建立需要依賴外部類物件,在沒有外部類例項之前無法建立非靜態內部類。
- 內部類是一個相對獨立的個體,與外部類沒有is-a(繼承)關係。
- 內部類可以直接訪問外部類的元素(包含私有域)
eg:
class Outer{ private String msg = "Hello World"; //內部類 //-------------------------------- class Inner{ public void print(){ System.out.println(msg); } } //--------------------------------
- 外部類不可以直接訪問內部類元素,需要通過內部類的間接引用訪問。
eg:
class Outer{
private String msg = "Hello World";
//內部類
//--------------------------------
class Inner{
public void print(){
System.out.println(msg);
}
}
//--------------------------------
public void fun(){
Inner in = new Inner();
in.print();
}
}
public class InnerClass{
public static void main(String[] args){
Outer out = new Outer();
out.fun();
}
}
建立內部類語法(在外部類外部)
- 建立非靜態內部類
外部類.內部類 內部類引用 = new 外部類().new 內部類();
Outter.Inner in = new Outter().new Inner();
- 建立靜態內部類
外部類.內部類 內部類引用 = new 外部類.內部類();
Outter.Inner in = Outter.Inner();
內部類的分類
- 成員內部類(成員方法)
a. 成員內部類內部不能存在任何static變數或方法,可以訪問外部靜態域。
因為static一定不依賴物件,但方法依賴於物件,這兩者很明顯有矛盾,所以成員內部類(成員方法)中不能存在static。
b. 成員內部類是依附外部類的,所以只有先建立了外部類才能建立內部類。
- 靜態內部類
a. 靜態內部類的建立不需要依賴外部類,可以直接建立。
b. 靜態內部類不可以使用任何外部類的非static域(包含屬性與方法),但可以存在自己的成員變數。 - 方法內部類
a. 方法內部類不允許使用訪問許可權修飾符public、private、protected均不允許。
b. 方法內部類對外部完全隱藏,除了建立這個類的方法可以訪問它以外,其他地方均不能訪問。
c. 方法內部類如果想要使用方法形參,該形參必須使用final宣告(JDK8將形參變為隱式final宣告)。
eg:
class Outter{
private int num;
public void display(int test){
class Inner{
private void fun(){
num++;
test++;//這是錯誤的,test是被final修飾的,不能被改變
System.out.println(num);
System.out.println(test);
}
}
new Inner().fun();
}
}
public class Test{
public static void main(String[] args){
Outter out = new Outter();
out.display(20);
}
}
- 匿名內部類(Lamdba表示式前身)
匿名內部類就是一個沒有名字的方法內部類。
特點與方法內部類完全相同,除此之外,還有兩個自己的特點:
a. 匿名內部類必須繼承一個抽象類或者實現一個介面。
b. 匿名內部類沒有構造方法,因為它沒有類名。