Java內部類以及使用場景


所謂內部類,即定義在另一個類中的類。那么,為什么會有內部類這個概念,他的使用場景又是什么呢?
首先,來看一下內部類的特點:

1. 它體現了一種代碼的隱藏機制和訪問控制機制,內部類與所在外部類有一定的關系,往往只有該外部類調用此內部類,所以沒有必要專門用一個Java文件存放這個類。

public class Outer {   private int num;   private class Inner {     private int num;   } }

一般的類是不允許用private修飾符的,但是內部類卻可以,該實例中,類Inner只對Outer可見,其他的類無法訪問的到Inner類。

注意,這里有個例外,如果內部類的訪問修飾符被設定為public,那么它是可以被其他類使用的,但是必須經由外部類來實例化內部類。

public class Outer { private int num = 1; public class Inner { private int num = 2; } public static void main(String[] args) { Outer outer = new Outer(); Inner inner = outer.new Inner(); System.out.println(inner.num); } }

2. 它包含有一個對外部類的this指針,從而可以訪問外部類的所有元素,包括所有public/private的成員和方法

public class Outer {
    private int num = 1;

    public class Inner {
        private int num = 2;
        private void func () {
            System.out.println(Outer.this.num);
        }
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        Inner inner = outer.new Inner();
        inner.func();
    }
}

另一方面,反向的,外部類對內部類的所有元素也都有訪問權,包括內部類的私有成員和方法:

public class Outer {
    private int num = 1;

    public class Inner {
        private int num = 2;
    }

    public void func () {
        Inner inner = new Inner();
        System.out.println(inner.num);
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.func();    // 2
    }
}

 

分類:

一、成員內部類

當某個類除了他的外部類,不會被其他類使用時,使用成員內部類。這種情況下,內部類依附於外部類而存在,原因可能有: 1. 不可能有其他類使用該內部類。 2. 該內部類不能被其他類使用,可能會導致錯誤。這是內部類使用比較多的一個場景。

1) 外部類可以直接訪問內部類的成員和方法,但是必須先創建一個內部類的對象,再通過該對象使用其成員和方法。

2) 內部類可以訪問外部類的成員和方法,但是要注意,當內部類擁有和外部類相同的成員或方法時,會發生隱藏現象,默認情況下訪問的是成員內部類的成員。如果要訪問外部類的同名成員,需要以下面的形式訪問:外部類.this.成員變量/方法

3) 內部類只是一個編譯時的概念,一旦編譯成功,就會成為完全不同的兩個類。對於一個名為Outer的外部類和其內部定義的名為Inner的內部類,編譯完后會生成Outer.class和Outer$Inner.class兩個類

4) 成員內部類與普通的成員沒什么區別,可以與普通成員一樣進行修飾和限制

public class Outer {
    private int num = 1;
    private int num1 = 10;

    public class Inner {
        private int num = 2;
        public void func () {
            System.out.println(Outer.this.num);
            System.out.println(num1);
        }
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        Inner inner = outer.new Inner();
        inner.func();
    }
}

 

二、局部內部類

 局部內部類是定義在一個方法或者一個作用域里面的類,它和成員內部類的區別在於局部內部類的訪問僅限於方法內或者該作用域內。局部內部類就像方法里面的局部變量一樣,是不能有public、protected、private及static修飾符的。

public class Outer {
    private int num = 1;
    private int num1 = 10;

    public void func () {
        class Inner {
            private int num = 2;
        }
        Inner inner = new Inner();
        System.out.println(inner.num);
    }


    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.func();
    }
}

 

三、靜態內部類

靜態內部類也是定義在另一個類里面的類,只不過在類的前面多了一個關鍵字static。靜態內部類是不需要依賴於外部類的,它不持有指向外部類對象的引用this,並且它不能使用外部類的非static成員或方法,這點很好理解,因為在沒有外部類的對象的情況下,可以創建靜態內部類的對象,如果允許訪問外部類的非static成員就會產生矛盾,因為外部類的非static成員必須依附於具體對象。它唯一的作用就是隨着類的加載(而不是隨着對象的產生)而產生。

public class Outer {

    static class Inner {
        public Inner () {

        }
    }

    public static void main(String[] args) {
        Outer.Inner innner = new Outer.Inner();
    }
}

 

 

四、匿名內部類

匿名內部類應該是平時我們編寫代碼時用的最多的,在編寫事件監聽的代碼時匿名內部類不但方便,而且使代碼更加容易維護。匿名內部類是唯一一種沒有構造器的類。正因為其沒有構造器,所以匿名內部類的使用范圍非常有限,大部分匿名內部類用於接口回調。匿名內部類在編譯的時候由系統自動起名為Outer$1.class。一般來說,匿名內部類用於集成其他類或者實現接口,並不需要增加額外的方法,只是對集成方法的實現或是重寫。

public class Outer {

    public void func () {
        System.out.println("1");
    }


    public static void main(String[] args) {
        Outer inner = new Outer() {
            public void func () {
                System.out.println("2");
            }
        };
        inner.func();
    }
}


總結:

1. 每個內部類都能獨立的集成一個接口的實現,所以無論外部類是否已經集成了某個(接口)實現,對於內部類都沒有影響。內部類使得多重集成的解決方案變得完整。

2. 方便將存在一定邏輯關系的類組織在一起,又可以對外界隱藏。

3. 方便編寫時間驅動程序。

4. 方便編寫線程代碼。


免責聲明!

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



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