1. 內部類的基本概念
1.1 內部類的定義
內部類: 所謂內部類就是在一個類內部進行其他類結構的嵌套操作。
class Outer{
private String str ="外部類中的字符串";
//**************************
//定義一個內部類
class Inner{
private String inStr= "內部類中的字符串";
//定義一個普通方法
public void print(){
//調用外部類的str屬性
System.out.println(str);
}
}
//**************************
//在外部類中定義一個方法,該方法負責產生內部類對象並調用print()方法
public void fun(){
//內部類對象
Inner in = new Inner();
//內部類對象提供的print
in.print();
}
}
public class Test{
public static void main(String[] args)
{
//創建外部類對象
Outer out = new Outer();
//外部類方法
out.fun();
}
}
運行結果:外部類中的字符串
但是如果去掉內部類:
class Outer{
private String outStr ="Outer中的字符串";
public String getOutStr()
{
return outStr;
}
public void fun(){ //2
//this表示當前對象
Inner in = new Inner(this); //3
in.print(); //5
}
}
class Inner{
private String inStr= "Inner中的字符串";
private Outer out;
//構造注入
public Inner(Outer out) //3
{
this.out=out; //4.為Inner中的out變量初始化
}
public void print(){ //6
System.out.println(out.getOutStr()); //7
}
}
public class Test{
public static void main(String[] args)
{
Outer out = new Outer(); //1.
out.fun(); //2.
}
}
執行結果:Outer中的字符串
但是去掉內部類之后發現程序更加難以理解。
1.2 內部類的優缺點
內部類的優點:
- 內部類與外部類可以方便的訪問彼此的私有域(包括私有方法、私有屬性)。
- 內部類是另外一種封裝,對外部的其他類隱藏。
- 內部類可以實現java的單繼承局限。
內部類的缺點:
結構復雜。
記錄:使用內部類實現多繼承:
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 String name() {
return new InnerClassA().name();
}
public int age() {
return new InnerClassB().age();
}
}
public class Test2 {
public static void main(String[] args) {
Outter outter = new Outter();
System.out.println(outter.name());
System.out.println(outter.age());
}
}
2. 創建內部類
2.1 在外部類外部 創建非靜態內部類
語法: 外部類.內部類 內部類對象 = new 外部類().new 內部類();
舉例: Outer.Inner in = new Outer().new Inner();
2.2 在外部類外部 創建靜態內部類
語法: 外部類.內部類 內部類對象 = new 外部類.內部類();
舉例: Outer.Inner in = new Outer.Inner();
2.3 在外部類內部創建內部類語法
在外部類內部創建內部類,就像普通對象一樣直接創建:Inner in = new Inner();
3. 內部類的分類
在Java中內部類主要分為成員內部類、靜態內部類、方法內部類、匿名內部類
3.1 成員內部類
類比成員方法
- 成員內部類內部不允許存在任何static變量或方法 正如成員方法中不能有任何靜態屬性 (成員方法與對象相關、靜態屬性與類有關)
class Outer {
private String name = "test";
public static int age =20;
class Inner{
public static int num =10;
public void fun()
{
System.out.println(name);
System.out.println(age);
}
}
}
public class Test{
public static void main(String [] args)
{}
}
2. 成員內部類是依附外部類的,只有創建了外部類才能創建內部類。
3.2 靜態內部類
關鍵字static可以修飾成員變量、方法、代碼塊、其實還可以修飾內部類,使用static修飾的內部類我們稱之為靜態內部類,靜態內部類和非靜態內部類之間存在一個最大的區別,非靜態內部類在編譯完成之后會隱含的保存着一個引用,該引用是指向創建它的外圍類,但是靜態類沒有。沒有這個引用就意味着:
1.靜態內部類的創建不需要依賴外部類可以直接創建。
2.靜態內部類不可以使用任何外部類的非static類(包括屬性和方法),但可以存在自己的成員變量。
class Outer {
public String name = "test";
private static int age =20;
static class Inner{
private String name;
public void fun()
{
System.out.println(name);
System.out.println(age);
}
}
}
public class Test{
public static void main(String [] args)
{
Outer.Inner in = new Outer.Inner();
}
}
3.3 方法內部類
方法內部類顧名思義就是定義在方法里的類
1.方法內部類不允許使用訪問權限修飾符(public、private、protected)均不允許。
class Outer{
private int num =5;
public void dispaly(final int temp)
{
//方法內部類即嵌套在方法里面
public class Inner{
}
}
}
public class Test{
public static void main(String[] args)
{}
}
2. 方法內部類對外部完全隱藏,除了創建這個類的方法可以訪問它以外,其他地方均不能訪問 (換句話說其他方法或者類都不知道有這個類的存在)方法內部類對外部完全隱藏,出了創建這個類的方法可以訪問它,其他地方均不能訪問。
3. 方法內部類如果想要使用方法形參,該形參必須使用final聲明(JDK8形參變為隱式final聲明)
class Outer{
private int num =5;
//普通方法
public void dispaly(int temp)
{
//方法內部類即嵌套在方法里面
class Inner{
public void fun()
{
System.out.println(num);
temp++;
System.out.println(temp);
}
}
//方法內部類在方法里面創建
new Inner().fun();
}
}
public class Test{
public static void main(String[] args)
{
Outer out = new Outer();
out.dispaly(2);
}
}
3.4 匿名內部類
匿名內部類就是一個沒有名字的方法內部類,因此特點和方法與方法內部類完全一致,除此之外,還有自己的特點:
1.匿名內部類必須繼承一個抽象類或者實現一個接口。
2.匿名內部類沒有類名,因此沒有構造方法。
//匿名內部類
//聲明一個接口
interface MyInterface {
//接口中方法沒有方法體
void test();
}
class Outer{
private int num = 5;
public void dispaly(int temp)
{
//匿名內部類,匿名的實現了MyInterface接口
//隱藏的class聲明
new MyInterface()
{
public void test()
{
System.out.println("匿名實現MyInterface接口");
System.out.println(temp);
}
}.test();
}
}
public class Test{
public static void main(String[] args)
{
Outer out = new Outer();
out.dispaly(3);
}
}
4. 內部類與外部類的關系
- 對於非靜態的內部類,內部類的創建依賴外部類的實例對象,在沒有外部類實例之前是無法創建內部類的。
- 內部類可以直接訪問外部類的元素(包括私有域)—外部類在內部類之前創建,創建內部類時會將外部類的對象傳入
class Outer{
//成員變量 與對象有關
private String msg;
private int age;
//--------------------------
class Inner{
public void dispaly()
{
//此處有一個隱藏的Outer.this
msg = "test";
age = 20;
System.out.println(msg);
System.out.println(age);
}
}
//--------------------------
public void test()
{
Inner in = new Inner();
in.dispaly();
}
}
public class Test{
public static void main(String[] args)
{
Outer out = new Outer();
out.test();
}
}
- 外部類可以通過內部類的引用間接訪問內部類元素 – -要想訪問內部類屬性,必須先創建內部類對象
class Outer{
public void dispaly()
{
//外部類通過創建內部類的對象間接訪問內部類元素
Inner in = new Inner();
in.dispaly();
}
class Inner{
public void dispaly()
{
System.out.println("內部類");
}
}
}
public class Test1{
public static void main(String[] args)
{
Outer out = new Outer();
out.dispaly();
}
}
- 內部類是一個相對獨立的個體,與外部類沒有關系。