Java的知識點14——內部類的概念、內部類的分類
內部類的概念
一般情況,我們把類定義成獨立的單元。有些情況下,我們把一個類放在另一個類的內部定義,稱為內部類(innerclasses)。
內部類可以使用public、default、protected 、private以及static修飾。
外部頂級類(我們以前接觸的類)只能使用public和default修飾。
注:內部類只是一個編譯時概念,一旦我們編譯成功,就會成為完全不同的兩個類。對於一個名為Outer的外部類和其內部定義的名為Inner的內部類。編譯完成後會出現Outer.class和Outer$Inner.class兩個類的位元組碼檔案。所以內部類是相對獨立的一種存在,其成員變數/方法名可以和外部類的相同。
內部類介紹
package cn.dym05; class Outer{ private int age=10; public void show() { System.out.println(age); } public class Inner{ //內部類中可以宣告與外部類同名的屬性與方法 private int age=20; public void show() { System.out.println(age); } } } public class Test01 { public static void main(String[] args) { } }
內部類的作用:
1. 內部類提供了更好的封裝。只能讓外部類直接訪問,不允許同一個包中的其他類直接訪問。
2. 內部類可以直接訪問外部類的私有屬性,內部類被當成其外部類的成員。 但外部類不能訪問內部類的內部屬性。
3. 介面只是解決了多重繼承的部分問題,而內部類使得多重繼承的解決方案變得更加完整。
內部類的使用場合:
1. 由於內部類提供了更好的封裝特性,並且可以很方便的訪問外部類的屬性。所以,在只為外部類提供服務的情況下可以優先考慮使用內部類。
2. 使用內部類間接實現多繼承:每個內部類都能獨立地繼承一個類或者實現某些介面,所以無論外部類是否已經繼承了某個類或者實現了某些介面,對於內部類沒有任何影響。
內部類的分類
在Java中內部類主要分為成員內部類(非靜態內部類、靜態內部類)、匿名內部類、區域性內部類
成員內部類(可以使用private、default、protected、public任意進行修飾。 類檔案:外部類$內部類.class)
非靜態內部類(外部類裡使用非靜態內部類和平時使用其他類沒什麼不同)
i. 非靜態內部類必須寄存在一個外部類物件裡。因此,如果有一個非靜態內部類物件那麼一定存在對應的外部類物件。非靜態內部類物件單獨屬於外部類的某個物件。
ii. 非靜態內部類可以直接訪問外部類的成員,但是外部類不能直接訪問非靜態內部類成員。
iii. 非靜態內部類不能有靜態方法、靜態屬性和靜態初始化塊。
iv. 外部類的靜態方法、靜態程式碼塊不能訪問非靜態內部類,包括不能使用非靜態內部類定義變數、建立例項。
成員變數訪問要點:
1. 內部類裡方法的區域性變數:變數名。
2. 內部類屬性:this.變數名。
3. 外部類屬性:外部類名.this.變數名。
內部類的訪問
package cn.dym05;
class Outer{
private int age=10;
class Inner{
int age=20;
public void show() {
int age=30;
System.out.println("內部類方法裡的區域性變數age:"+age); //30
System.out.println("內部類的成員變數age:"+this.age);//20
System.out.println("外部類的成員變數age:"+Outer.this.age); //10
}
}
}
public class Test02 {
public static void main(String [] args) {
//先建立外部類例項,然後使用該外部類例項建立內部類例項
Outer.Inner inner=new Outer().new Inner();
inner.show();
Outer outer=new Outer();
Outer.Inner inn=outer.new Inner();
inn.show();
}
}
//先建立外部類例項,然後使用該外部類例項建立內部類例項
靜態內部類
使用要點:
1. 當一個靜態內部類物件存在,並不一定存在對應的外部類物件。 因此,靜態內部類的例項方法不能直接訪問外部類的例項方法。
2. 靜態內部類看做外部類的一個靜態成員。 因此,外部類的方法中可以通過:“靜態內部類.名字”的方式訪問靜態內部類的靜態成員,通過 new 靜態內部類()訪問靜態內部類的例項。
靜態內部類的訪問
靜態內部類相當於外部類的一個靜態成員,通過 new 外部類名.內部類名() 來建立內部類物件
package cn.dym05;
class Outer{
private int age=10;
static class Inner{
int age=20;
public void show() {
int age=30;
System.out.println("內部類方法裡的區域性變數age:"+age); //30
System.out.println("內部類的成員變數age:"+this.age);//20
//System.out.println("外部類的成員變數age:"+Outer.this.age); //不能訪問
}
}
}
public class Test02 {
public static void main(String [] args) {
//通過 new 外部類名.內部類名() 來建立內部類物件
Outer.Inner inner=new Outer.Inner();
inner.show();
}
}
匿名內部類
匿名內部類適合那種只需要使用一次的類。比如:鍵盤監聽操作等等
注:1. 匿名內部類沒有訪問修飾符。
2. 匿名內部類沒有構造方法。因為它連名字都沒有那又何來構造方法呢。
區域性內部類
還有一種內部類,它是定義在方法內部的,作用域只限於本方法,稱為區域性內部類。
方法中的內部類
package cn.dym05;
public class Test04 {
public void show() {
//作用域僅限於該方法
class Inner{
public void fun() {
System.out.println("helloworld");
}
}
new Inner().fun();
}
public static void main(String[] args) {
new Test04().show();
}
}