Java內部類的定義、如何創建內部類、內部類的分類、內部類與外部類的關系


 

 

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 內部類的優缺點

內部類的優點:

  1. 內部類與外部類可以方便的訪問彼此的私有域(包括私有方法、私有屬性)。
  2. 內部類是另外一種封裝,對外部的其他類隱藏。
  3. 內部類可以實現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 成員內部類

類比成員方法

  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();
    }
}
 
  • 內部類是一個相對獨立的個體,與外部類沒有關系。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM