1. 程式人生 > >內部類詳解(含java8新特性)

內部類詳解(含java8新特性)

內部類的作用:

  1. 提供很好的封裝,不允許同一個包中的其他類訪問!
  2. 內部類成員能直接訪問外部類的私有資料
  3. 匿名內部類適用於建立僅僅需要使用一次的類

內部類分類:

  1. 非靜態內部類
  2. 靜態內部類(類內部類)
  3. 成員內部類
  4. 匿名內部類

非靜態內部類注意事項:

  1. 非靜態內部類的成員可訪問外部類的private成員,反過來不成立
    —原因:外部類物件訪問非靜態內部類成員時,可能非靜態內部類物件根本不存在!而非靜態內部類物件訪問外部類成員時,外部類物件一定存在!
  2. 不允許在外部類的靜態成員中直接使用非靜態內部類!
  3. 非靜態內部類裡不能有靜態方法,靜態成員變數,靜態初始化程式碼塊!

總之:就是一個先來後到問題,先有外部類,才能有非靜態內部類

靜態內部類注意事項:

  1. static修飾的,所以這個內部類屬於外部類本身,也叫類內部類!
  2. 靜態內部類可以包含靜態成員,也能包含非靜態成員,靜態成員不能訪問非靜態成員!(又是先來後到問題)
  3. java允許在介面中定義內部類,預設使用public static修飾!

區域性內部類
把一個內部類放在方法裡定義,這個內部類就是區域性內部類,僅在該方法裡有效!不能有訪問控制符和static修飾符!作用域是當前方法!很少使用!
注意事項:

  1. 只能用預設訪問修飾符

匿名內部類
建立那種只需要一次使用的類,必須繼承一個父類或者實現一個介面!
語法:
new 實現介面()|父類構造器(實參列表)
{
//匿名內部類的實體部分
}
匿名內部類不能是抽象類,不能定義構造器!
java8以前,java要求被區域性內部類,匿名內部類訪問的區域性變數必須使用final修飾,java8以後,這個限制取消了!

使用靜態內部類和非靜態內部類
宣告變數的語法完全一樣
格式:OuterClass.InnerClass varName
建立的時候有所區別:
非靜態內部類:必須使用外部類物件呼叫構造器

Out.In in=new out().new In();

靜態內部類:只需使用外部類就能呼叫構造器

StaticOut.StaticIn in=new StaticOut.StaticIn();

例項:
抽象類I,含有抽象方法getPrice()

public abstract class I {
    public abstract double getPrice();
}

TestClass包含四種內部類!

public class TestClass {
    //成員變數
    private int i=0;
    //成員方法
    //I是一個抽象類,含有抽象方法
    public void test1(I i){
        System.out.println("成員方法");
    }
    //成員內部類Inner2,修飾符public
    public class Inner2{

    }
    //成員內部類Inner3,修飾符protected
    protected class Inner3{

    }
    //成員內部類Inner1,修飾符預設
    class Inner1{

    }
    //成員內部類(就是作為外部類的成員)Inner,修飾符private
    private class Inner{

    }
    //成員方法
    public void test(){
        //區域性內部類(內部類定義在方法和作用域內)
        /*編譯器報錯,修飾符不能是public*/
        public  class Inner4{

        }
        //區域性內部類
        /*編譯器報錯,修飾符不能是protected */
        protected class Inner6{

        }
        //區域性內部類
        class Inner5{

        }
        //區域性內部類
        /*編譯器報錯,修飾符不能是private*/
        private class Inner7{

        }
    }
    //靜態內部類(static+成員內部類)
    public static class Inner10{

    }

    protected  static class Inner11{

    }
    static class  Inner9{

    }
    private static class Inner8{

    }
    //匿名內部類
    public static void main(String[] args) {
        TestClass test2=new TestClass();
        test2.test1(new I(){
            @Override
            public double getPrice() {
                System.out.println("匿名內部類");
                return 0;
            }

        });
    }

}