1. 程式人生 > >Java筆記之內部類、匿名內部類詳解

Java筆記之內部類、匿名內部類詳解

內部類

內部類訪問特點:

1、內部類可以直接訪問外部類中的成員

2、外部類要訪問內部類,必須建立內部類的物件

class Outer
{
    private int num=3;
    class Inner //內部類
    {
        void show()
        {
            System.out.println("show run..."+num);//直接訪問
        }
    }
    public void method()
    {
        Inner in =new Inner();//需要建立內部類的物件
        in.show();
    }
}


一般用於類的設計

分析事物時,發現該事物描述中還有事物,而且這個事物還在訪問被描述事務的內容。

這時就把還有的事物定義成內部類來描述。

先說明一下static ,隨著類的載入,static 變數首先被載入進記憶體! 

class Outer
{
    private static int num =3;
    static class Inner //內部類
    {
        void show ()
        {
            System.out.println("show run..."+num);
        }
        static void function ()//如果該內部類中定義了靜態成員,這個內部類必須是靜態的。
        {
            System.out.prtintln("function"+num);
        }
    }
public void method ()   
{
    Inner in =new Inner();
    in.show();

}
class InnerClassDemo
{
    public static void main (String[] args)
    {
        //Outer out =new Outer();    
        //out.method();
        //直接訪問外部類中的內部類中的成員
        //Outer.Inner in =new Outer().new Inner();
        //in.show();
        
        //如果內部類是靜態的。相當於一個外部類
        Outer.Inner in =new Outer.Inner();
        in.show();
        //如果內部類時靜態的,成員是靜態的,則:
        Outer.Inner.function();
            
        

    }
}

為什麼內部類能直接訪問外部類中的成員呢?

那是因為內部類持有了外部類的引用。 呼叫方法:外部類名.this.成員名

class Outer
{
    int num =3;
    class Inner
    {
        int num =4;
        void show ()
        {
            int num =5;
            System.out.println(Outer.this.num);
        }

    }
    void method ()
       {
        new Inner().show();        

        }
}

內部類可以存放在區域性位置上,內部類在區域性位置上只能訪問區域性中被final修飾的區域性變數(常量)

class Outer
{
    int num =3;
    void method(final int y )
    {
        final int x=0;//從內部類中訪問區域性變數x,需要被宣告為最終型別
        class Inner
        {
            void show()
            {
            System.out.println("show..."+num);
            System.out.ptintln("show..."+x);//從內部類中訪問區域性變數x,需要被宣告為最終型別
            System.out.println("show..."+y);//從內部類中訪問區域性變數x,需要被宣告為最終型別
            }
        }
       Inner in =new Inner();
       in.show();
    }
    //不能在另外一個方法裡面建立Inner物件,因為她不知道這個方法裡面有inner
}

匿名內部類。就是內部類的簡寫格式。

必須由前提。

內部類必須繼承或者實現一個外部類或者介面。

匿名內部類:其實就是一個匿名子類物件

格式:new 父類or介面(){子類內容}

abstract class Demo
{
    abstract void show1();
    abstract void show2();
}
/*通常的使用場景之一:
當函式引數是介面型別時,而且介面中的方法不超過三個
可以用匿名內部類作為實際引數進行傳遞
*/
class Outer
{
    int num =4;
       
    public void method()
    {
        Demo in=new Demo()    //匿名內部類
            {
                void show()
                {
                    System.out.println("show1......"+num);
                   }
                void show2()
                  {
                     System.out.println("show2......"+num);
                    }
            };
            in.show1();
            in.show2();   


    }

}

匿名內部類的應用:

/*通常的使用場景之一: 當函式引數是介面型別時,而且介面中的方法不超過三個 可以用匿名內部類作為實際引數進行傳遞 */

inerface Inter
{
    void show1();
    void show2();
}

class Demo_Inner
{
    public static void main(String[] args)
    {
        System.out.println("Hello world!");
        show(new Inter()
        {
            public void show1();
            public void show2();
        });
    }
    public static void show(Inter in )
    {
        in.show1();
        in.show2();
    }
    

}

面試題,重要!

1、

class Outer
{
       void method()
        {
            new Object()
            {
                 public void show()
                   {
                        System.out.println("show run");                       

                        }   
             }.show(); //編譯成功

        }

}

2、

class Outer
{
       void method()
        {
            Object obj = new Object()
            {
                 public void show()
                   {
                        System.out.println("show run");                       

                        }   
             };
                obj.show();//編譯失敗:因為匿名內部類這個子類物件被向上轉型為Object型別
                                       //這樣就不能再使用子類特頭的方法了。
            

        }

}