Java 內部類(成員內部類、局部內部類、靜態內部類,匿名內部類)

1、什麼是內部類?

  內部類是指在一個外部類的內部再定義一個類。內部類做爲外部類的一個成員,而且依附於外部類而存在的。內部類可爲靜態,可用protected和private修飾(而外部類只能使用public和缺省的包訪問權限)。函數

   內部類主要有一下幾種:成員內部類、局部內部類、靜態內部類、匿名內部類學習

2、內部類的共性:

(1)、內部類仍然是一個獨立的類,在編譯以後內部類會被編譯成獨立的.class文件,可是前面冠之外部類的類名和$符號 。this

(2)、內部類不能用普通的方式訪問。spa

(3)、內部類聲明成靜態的,就不能隨便的訪問外部類的成員變量了,此時內部類只能訪問外部類的靜態成員變量 。3d

(4)、外部類不能直接訪問內部類的的成員,但能夠經過內部類對象來訪問code

 

3、爲何須要內部類?

其主要緣由有如下幾點:對象

  一、內部類方法能夠訪問該類定義所在的做用域的數據,包括私有的數據blog

  二、內部類能夠對同一個包中的其餘類隱藏起來,通常的非內部類,是不容許有 private 與protected權限的,但內部類能夠繼承

  三、能夠實現多重繼承接口

  四、當想要定義一個回調函數且不想編寫大量代碼時,使用匿名內部類比較便捷

使用內部類最吸引人的緣由是:

  每一個內部類都能獨立地繼承自一個(接口的)實現,因此不管外圍類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。你們都知道Java只能繼承一個類,它的多重繼承在咱們沒有學習內部類以前是用接口來實現的。但使用接口有時候有不少不方便的地方。好比咱們實現一個接口就必須實現它裏面的全部方法。而有了內部類就不同了。它可使咱們的類繼承多個具體類或抽象類。

4、代碼實現

  一、成員內部類

即在一個類中直接定義的內部類,成員內部類與普通類的成員沒什麼區別,能夠與普通成員同樣進行修飾和限制。成員內部類不能含有static的變量和方法。

package com.test; public class Outer { private static int number = 100; private int j = 20; private String name = "Java"; public static void outer_funOne(){ System.out.println("外部類Outer的靜態方法:outer_funOne"); } public void outer_funTwo(){ System.out.println("外部類的普通方法:outer_funTwo"); } //成員內部類,能夠訪問外部類的全部成員
    class Demo{ //內部類不容許定義靜態變量 //static int demo_i = 100;
        int j =50; //內部類和外部類的實例變量能夠共存 //成員內部類中的方法定義
        public void demo_funOne(){ //內部類中訪問內部類本身的變量直接用變量名 //也能夠用 this.j
 System.out.println(j); //內部類中訪問外部類的成員變量語法:外部類類名.this.變量名
            System.out.println("內部類訪問外部類變量:"+Outer.this.j); //若是內部類中沒有與外部類中有相同的變量,則能夠直接用變量名使用
 System.out.println(name); //內部類調用外部類方法
            outer_funOne();  //靜態方法
            outer_funTwo();  //非靜態方法
 } } public static void outer_funThree(){ //外部類靜態方法訪問成員內部類 // 一、創建外部類對象
        Outer out = new Outer(); // 二、根據外部類創建內部類對象
        Demo demo = out.new Demo(); // 訪問內部類方法
 demo.demo_funOne(); //訪問內部類字段
        System.out.println("內部類成員字段:"+demo.j); } public static void main(String[] args) { //調用內部類的方法 // 一、建立外部類對象
        Outer out = new Outer(); // 二、經過外部類對象建立內部類對象
        Outer.Demo demo = out.new Demo(); // 一、2步簡寫 // Outer.Demo demo1 = new Outer().new Demo(); //方法調用
 demo.demo_funOne(); } }

結果:

  二、局部內部類

    在方法中定義的內部類稱爲局部內部類。與局部變量相似,局部內部類不能有訪問說明符,由於它不是外圍類的一部分,可是它能夠訪問當前代碼塊內的常量,和此外圍類全部的成員。

須要注意的是:

  (1)、局部內部類只能在定義該內部類的方法內實例化,不能夠在此方法外對其實例化。

  (2)、局部內部類對象不能使用該內部類所在方法的非final局部變量。

 

package com.test; public class Outer { private static int number = 100; private int j = 20; private String name = "Java"; //定義外部類方法
    public void outer_funOne(int k){ final int number = 100; int j = 50; //方法內部的類(局部內部類)
        class Demo{ public Demo(int k){ demo_funOne(k); } int number = 300; //能夠定義與外部類同名的變量 // static int j = 10; //不能夠定義靜態變量 //內部類的方法
            public void demo_funOne(int k){ System.out.println("內部類方法:demo_funOne"); //訪問外部類的變量,若是沒有與內部類同名的變量,則可直接用變量名
 System.out.println(name); //訪問外部類與內部類同名的變量
                System.out.println(Outer.this.number); System.out.println("內部類方法傳入的參數是:"+k); } } new Demo(k); } public static void main(String[] args) { //訪問內部類必需要先有外部類對象
        Outer out = new Outer(); out.outer_funOne(11); } }

 

 

 結果:

  三、靜態內部類(嵌套類)

  若是你不須要內部類對象與其外圍類對象之間有聯繫,那你能夠將內部類聲明爲static。這一般稱爲嵌套類(nested class)。想要理解static應用於內部類時的含義,你就必須記住,普通的內部類對象隱含地保存了一個引用,指向建立它的外圍類對象。然而,當內部類是static的時,就不是這樣了。嵌套類意味着:

  1. 要建立嵌套類的對象,並不須要其外圍類的對象。

  2. 不能從嵌套類的對象中訪問非靜態的外圍類對象。

 

package com.test; public class Outer { private static int number = 100; private int j = 20; private String name = "Java"; public static void outer_funOne(){ System.out.println("外部類靜態方法:outer_funOne"); } public void outer_funTwo(){ } //靜態內部類能夠用public、protected、private修飾 //靜態內部類能夠定義靜態類或非靜態內部類
    private static class Demo{ static int j = 100; String name = "C#"; //靜態內部類裏的靜態方法
        static void demo_funOne(){ //靜態內部類只能訪問外部類的靜態成員(靜態變量、靜態方法)
            System.out.println("靜態內部類訪問外部類靜態變量:"+number); outer_funOne();//訪問外部類靜態方法
 } //靜態內部類非靜態方法
        void demo_funTwo(){ } } public void outer_funThree(){ //外部類訪問內部類靜態成員:內部類.靜態成員
 System.out.println(Demo.j); //訪問靜態方法
 Demo.demo_funOne(); //訪問靜態內部類的非靜態成員,實例化內部類便可
        Demo demo = new Demo(); //訪問非靜態變量
 System.out.println(demo.name); //訪問非靜態方法
 demo.demo_funTwo(); } public static void main(String[] args) { new Outer().outer_funThree(); } }

 

 

 結果:

  三、匿名內部類

簡單地說:匿名內部類就是沒有名字的內部類。什麼狀況下須要使用匿名內部類?若是知足下面的一些條件,使用匿名內部類是比較合適的:

  一、只用到類的一個實例。

  二、類在定義後立刻用到。

  三、類很是小(SUN推薦是在4行代碼如下)

  四、給類命名並不會致使你的代碼更容易被理解。

在使用匿名內部類時,要記住如下幾個原則:
  一、 匿名內部類不能有構造方法。
  二、 匿名內部類不能定義任何靜態成員、方法和類。
  三、 匿名內部類不能是public,protected,private,static。
  四、 只能建立匿名內部類的一個實例。
  五、   一個匿名內部類必定是在new的後面,用其隱含實現一個接口或實現一個類。
  六、 因匿名內部類爲局部內部類,因此局部內部類的全部限制都對其生效。

   代碼。。。。。。。。

相關文章
相關標籤/搜索