前言
由于平時使用內部類不多,所以對內部類只有一個很淺的認知,趁著春節有空,整理了一些內部類的使用筆記,
使用內部類的好處
使用內部類可以很好地解決多重繼承的問題,每個內部類都能獨立地繼承一個(介面的)實作,
內部類的分類
成員內部類
靜態內部類
方法內部類
匿名內部類
1.成員內部類
private int num = 100;
String name = "zhou";
public class Inner{
String name = "Inner Zhou";
public void print(){
System.out.println(Demo.this.name); //當內部類屬性名和外部類屬性名一樣時,外部類需要(外部類.this.屬性)來呼叫
System.out.println(name);//當內部類屬性名和外部類屬性名一樣時,默認呼叫內部類屬性
System.out.println(num);
}
}
public static void main(String[] args){
Demo o = new Demo();
Inner in = o.new Inner();
in.print();
}
}
- 成員內部類可以使用任意訪問控制符,如 public 、 protected 、 private 等,
- 外部類可以直接訪問成員內部類中的資料,而不受訪問控制符的影響,如直接訪問Demo類中的私有屬性num,
- 當成員內部類的屬性名和外部類的屬性名一樣時,默認呼叫成員內部類屬性,如上面代碼中,Demo類中的name屬性與Inner中name屬性名稱一樣,那么System.out.println(name);是默認呼叫的是Inner的name屬性,
- 成員內部類必須使用外部類物件來創建成員內部類物件,而不能直接去 new 一個內部類物件,即:內部類 物件名 = 外部類物件.new 內部類( ),
- 上述編譯程式后,會產生了兩個 .class 檔案: Demo.class,Demo$Inner.class{},
- 成員內部類中不能存在任何static 的變數和方法,可以定義常量,
2.靜態內部類
private int num = 100;
String str = "zhou";
static String name = "zhou";
public static class Inner{
String name = "Inner Zhou";
public void print(){
System.out.println(new Demo().str);
System.out.println(Demo.name);
System.out.println(name);
}
}
public static void main(String[] args){
Inner in = new Inner();
in.print();
}
}
- 靜態內部類不能直接訪問外部類的非靜態成員,但可以通過【new 外部類().成員】 的方式訪問
- 如果外部類的靜態成員與內部類的成員名稱相同,可通過【類名.靜態成員】訪問外部類的靜態成+ 員,否則可通過【成員名】直接呼叫外部類的靜態成員,
- 創建靜態內部類的物件時,可以直接創建 內部類 物件名 = new 內部類();
3.方法內部類
String a = "zhou a";
public void show() {
String b = "Zhou b";
class Inner {
String c = "Zhou c";
public void print(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
Inner i = new Inner();
i.print();
}
public static void main(String[] args) {
Demo demo = new Demo();
demo.show();
}
}
- 方法內部類不能有 public、protected、private 以及 static 修飾符
- jdk8版本之前,只能訪問方法中定義的 final 型別的區域變數,
- jdk1.8版本之后,新增了 Effectively final功能,方法內部類和匿名內部類中呼叫方法中的區域變數,可以不需要修飾為 final,下面是檔案的原話:
However, starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.
- 4.反編譯jdk8編譯之后的class檔案,內部類參考外部的區域變數都是 final 修飾的,
4.匿名內部類
public InnerClass getInnerClass(String str){
return new InnerClass(){
{
a = 2; //利用構造代碼塊能夠達到為匿名內部類創建一個構造器的效果
}
public String getStr(){
return str;
}
};
}
abstract class InnerClass {
int a;
abstract String getStr();
}
//也可以是介面
/*interface InnerClass{
String getStr();
}*/
public static void main(String[] args) {
Demo demo = new Demo();
InnerClass inner = demo.getInnerClass("zhou");
System.out.println(inner.getStr());
System.out.println(inner.a);
}
}
- 創建匿名內部類時它會立即創建一個該類的實體,
- 使用匿名內部類時,必須繼承一個類或者實作一個介面,但同時也只能繼承一個類或者實作一個介面,
- 匿名內部類中不能定義建構式,不能存在任何的靜態成員變數和靜態方法,
- 匿名內部類不能是抽象的,它必須要實作繼承的類或者實作的介面的所有抽象方法,
- 匿名內部類初始化:可以使用構造代碼塊達到為匿名內部類創建一個構造器的效果,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/547452.html
標籤:Java
