所謂的內部類(Inner Class),顧名思義,就是將一個類定義在另外一個類的內部。一個類內部的類被稱之爲內部類。this
// Outer 爲外部類,Inner 爲內部類 public class Outer{ class Inner{ // ... } }
內部類間接實現多繼承
示例:code
public class MultiExtends{ public static void main(String[] args){ C c = new C(); // 訪問 A 類中的 showA() 方法 c.getInstanceA1(); // 訪問 B 類中的 showB() 方法 c.getInstanceB1(); } } class A{ public void showA(){ System.out.println("A"); } } class B{ public void showB(){ System.out.println("B"); } } // 至關於同時繼承了 A 類和 B 類 class C{ // 內部類 A1 private class A1 extends A{ public void showA(){ // 繼承 A 類的 showA()方法 supper.showA(); } } // 內部類 B1 private class B1 extends B{ public void showB(){ // 繼承 B 類的 showB()方法 supper.showB(); } } // 給外部提供訪問內部私有類 A1 內的方法 的接口 public void getInstanceA1(){ new A1().showA(); } // 給外部提供訪問內部私有類 B1 內的方法 的接口 public void getInstanceB1(){ new B1().showB(); } }
內部類實現父類與接口中的同名方法
示例:對象
public class MutilExtendsImplement{ public static void main(String[] args){ Son son = new Son(); // 訪問抽象父類的 show() 方法 son.show(); // 訪問接口中的 show() 方法 son.showSonInner(); } } // 抽象類 abstract class Parent{ // 抽象類中的 show() 抽象方法 public abstract void show(); } // 接口 interface IShow{ // 接口中的 show() 方法 // public void show(); public void show1(); } // 這種作法是不容許的,由於 Parent 類和 IShow() 存在同名方法 show(), Son 類不知道該實現哪一個 show() 方法 ,除非 抽象父類或者接口任一個修改方法名 // Son 類繼承 Parent 類並實現 IShow 接口 class Son extends Parent implements IShow{ // 實現抽象父類 public void show(){ ... } // 接口中的方法名改成 show1() public void show1(){ ... } } // 若抽象父類和接口都不修改方法名,能夠由內部類來實現 // 抽象類 abstract class Parent{ // 抽象類中的 show() 抽象方法 public abstract void show(); } // 接口 interface IShow{ // 接口中的 show() 方法 public void show(); } class Son extends Parent{ // 實現抽象父類的 show() 方法 public void show(){ System.out.println("抽象類中的 show() 方法"); } // 定義一個內部類來實現 IShow 接口 private class SonInner implements IShow{ // 實現接口的 show() 方法 public void show(){ System.out.println("接口中的 show() 方法"); } } // 提供給外部訪問私有內部類 SonInner 方法的接口 public void showSonInner(){ new SonInner.show(); } }
成員內部類特色:繼承
注:若成員內部類與外部類有同名方法或同名屬性,成員內部類在訪問外部類的同名方法或屬性時要使用「外部類名.this.(外部)成員方法(屬性)」形式,若成員內部類訪問的是與外部內非同名的方法或屬性,直接使用「方法名」或「屬性名」訪問便可接口
示例:作用域
public class MenberInnerClass{ // 程序主方法 public static void main(String[] args){ Outer outer = new Outer(); // 建立內部成員類實例 Outer.Inner innre = outer.new Inner(); } } // 外部類 Outer class Outer{ // 外部類屬性 private String name; private int number; // 外部類方法 public void showOuter(){ System.out.println(name); System.out.println(number); // 外部類不能直接訪問內部類的成員方法和屬性 // System.out.println(number2); } // 內部類 Inner public class Inner{ private String name; private int number2; // 在成員內部類中不能聲明靜態的成員,包括屬性和方法 // public static int number3 = 30; // 在成員內部類中能夠聲明靜態的常量 private static final int number3 = 30; public void showInner(){ System.out.println(name); System.out.println(number2); // 內部類調用外部類成員 System.out.println(Outer.this.name); // 內部類調用外部類方法 Outer.this.showOuter(); } } }
靜態內部類特色get
Outer.Inner inner = new Outer.Inner();
靜態內部類有如下限制io
StaticInner.name
匿名內部類特色class
匿名內部類語法變量
new interface/superclass() {//類體}
示例:
public class AnonymousInnerClass{ public static void main(String[] args){ Person person = new Person(); // 利用匿名內部類實例化 Animail 的一個子類 person.feed(new Animial(){ // 實現抽象類中的抽象方法 eat() public void eat(){ System.out.println("eating"); } }); // 利用匿名內部類實現接口 Animail persion.feed(new Animail(){ public void move(){ System.out.println("moving"); } }); } } class Person{ // feed 方法傳入 Animial 對象執行 eat() 方法 public void feed(Animail animail){ animail.eat(); } } // 抽象父類 Animail abstract class Animail{ // 抽象方法 eat() public abstract void eat(); } // 接口 Animail interface Animail{ public void move(); }
局部內部類特色
局部內部類有如下限制
示例:
public class LocalInnerClass{ public static void main(String[] args){ Outer outer = new Outer(); // 經過調用 Outer 的 showOuter() 方法來調用局部內部類 Inner outer.showOuter(); } } class Outer{ private String name = "tom"; private int num1 = 10; public void showOuter(){ // 局部變量 int num2 = 20; // 局部內部類 Inner,定義在 showOuter() 方法中 class Inner{ private String name = "jack"; private int num3 = 30; public void showInner(){ System.out.println(name); System.out.println(num3); } } // 構造局部內部類的實例,只能在當前這個方法的做用域內構造 Inner inner = new Inner(); inner.showInner(); } }