天天看點

内部類

17.内部類

    将一個類定義在另一個類的裡面,對裡面那個類就稱為内部類(内置類,嵌套類)。

    通路特點:

        内部類可以直接通路外部類中的成員,包括私有成員。

        而外部類要通路内部類中的成員必須要建立内部類的對象。

18.内部類的位置

    1.内部類定義在成員位置上

        可以被private static成員修飾符修飾。

        被static修飾的内部類隻能通路外部類中的靜态成員。

     2.内部類定義在局部位置上

        也可以直接通路外部類中的成員。

        同時可以通路所在局部中的局部變量,但必須是被final修飾的。

19.匿名内部類

        就是内部類的簡化寫法。

    前提:

        内部類可以繼承或實作一個外部類或者接口。

    格式為:

        new 外部類名或者接口名(){覆寫類或者接口中的代碼,(也可以自定義内容。)}

    簡單了解:

        就是建立一個帶内容的外部類或者接口的子類匿名對象。

class Outer{
    private int num = 3;
    static int num2 = 7;
     
    //内部類:定義在成員位置上,它就相當于外部類的成員一樣,可以被成員修飾符所修飾。
    public class Inner{
        void show(){
        System.out.println("show num="+num);
        }
    }
     
    void method(){
        //外部類要通路内部類中的成員,必須要建立内部類中的對象
        Inner in = new Inner();
        in.show();
    }
     
     
    static class Inner2{//被static修飾的内部類隻能通路外部類中的靜态成員
        void show2(){
        System.out.println("show2 num2="+num2);
        }
    }
     
    static class Inner3 {
        //當内部類中定義了靜态成員,該内部類必須被靜态修飾
        static void show3(){
        System.out.println("show3 num2="+num2);
        }
    }
 
}
 
 
class  InnerDemo{
    public static void main(String[] args) {
        /*
        直接通路内部類成員的方式。
        */
        //1,對非靜态的内部類中的非靜态成員通路。
        Outer.Inner in = new Outer().new Inner();
        in.show();
         
        //2,通路靜态内部類中的非靜态成員。
        Outer.Inner2 in = new Outer.Inner2();
        in.show2();
         
        //3,通路靜态内部類中的靜态成員。
        Outer.Inner3.show3();
             
        //外部類通路外部類的方法,該方法中有内部類對象通路的方法
        Outer out = new Outer();
        out.method();
    }
}      

内部類直接通路外部類成員的原因

非靜态的内部類之是以能直接通路外部類成員的原因是:它持有了一個外部類對象的引用。

class Outer{
    private int num = 2;
    class Inner{
        private int num = 3;
        void show(){
            int num = 4;
            System.out.println("num="+num);  //結果是4
            System.out.println("num="+this.num);  //結果是3
            System.out.println("num="+Outer.this.num);  //結果是2
        }
    }
   
    void method(){
        new Inner().show();
    }
}      
class Outer{
    private int num = 3;
    void method(){
        final int x = 7;   //内部類定義在局部中,隻能通路被final修飾的局部變量。
        //不被final修飾的局部變量生命周期随着方法的釋放而釋放。
         class Inner{//定義在局部的内部類。
             void show(){
                System.out.println("x="+x);
                //System.out.println("num="+num);
            }
    }
    
    new Inner().show();
    }
}
 

class Outer2{
    private int num = 4;
    Object obj ; 
    public void method(){
        final int x = 4;
        class Inner{
            public String toString(){
                return "hahah"+x;
            }
        }
        this.obj = new Inner();
    }
}      
class InnerDemo3 {
    public static void main(String[] args) {
        //new Outer().method();
        Outer2 out = new Outer2();
        out.method();
        System.out.println(out.obj.toString());
    }
}      
/*
匿名内部類的形式。
其實就是對内部類進行簡化書寫。
必須有前提:
内部類必須繼承或者實作類或接口。
 
格式:
new 父類名或者接口名(){定義内部類的内容;}
 
匿名内部類其實就是一個子類匿名對象。
 
*/
 
abstract class AbsDemo{
    abstract void function();
}
 
class Outer{
    int num = 4;
    /*
    class Inner extends AbsDemo{
        void function(){
        System.out.println("num="+num);
        }
         
    }
    */
    void method(){
        //new Inner().function();
        new AbsDemo() {  //建立了子類的對象并且調用了子類的方法。
                       //對内部類的描述。
            void function(){
            System.out.println("num===="+num);
            }
        }.function();  //枚紅色的部分是綠色部分的簡寫, new X(){}是建立X子類對象
    }
}
 
class NoNameInnerDemo {
public static void main(String[] args) {
    Outer out = new Outer();
    out.method();
    }
}      

繼續閱讀