Java內部類


內部類簡介


Java 一個類中能夠嵌套另一個類,語法格式以下:html

class OuterClass {   // 外部類
    // ...
    class NestedClass { // 嵌套類,或稱爲內部類
        // ...
    }
}

嵌套類有以下幾種類型:java

image


成員內部類


最簡單的一種內部類,形式以下,跟其餘變量同樣,是一個類中的一個成員jvm

class Outer {
    
    String str = "hello";
     
    public Outer(String str) {
        this.str = str;
    }
    
    /* 內部類 */
    class Inner {     
        public void showStr() {
            System.out.println(str);
        }
    }
}

  • 成員內部類能夠無條件地訪問外部類的全部元素
  • 外部類訪問內部類須要先建立一個內部類對象
  • 成員內部類是依附外部類而存在
能夠訪問外部類原理

編譯器會在編譯時生成外部類和內部類兩個字節碼文件,還會給內部類的無參構造函數增長一個參數,爲外部類的一個應用,且指向了外部類,故能夠隨意使用外部類一切。函數

側面說明成員內部類依賴於外部類的優先建立,否則會初始化失敗this


局部內部類


定義在一個方法或者一個做用域裏面的類,局部內部類的訪問僅限於方法內或者該做用域內spa

class MyClass{
    public MyClass() {
         
    }
}
 
class Outer{
    public Outer(){
         
    }
     
    public MyClass getInner{
        
        /* 局部內部類 */
        class Inner extends MyClass{   
            int age = 0;
        }
        return new Inner();
    }
}

局部內部類就像是方法裏面的一個局部變量同樣,是不能有 public、protected、private 以及 static 修飾符的線程


匿名內部類


先看一下官方給的例子code

public class HelloWorldAnonymousClasses {

    /**
     * 包含兩個方法的HelloWorld接口
     */
    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }

    public void sayHello() {

        // 一、局部類EnglishGreeting實現了HelloWorld接口
        class EnglishGreeting implements HelloWorld {
            String name = "world";
            public void greet() {
                greetSomeone("world");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hello " + name);
            }
        }

        HelloWorld englishGreeting = new EnglishGreeting();

        // 二、匿名類實現HelloWorld接口
        HelloWorld frenchGreeting = new HelloWorld() {
            String name = "tout le monde";
            public void greet() {
                greetSomeone("tout le monde");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Salut " + name);
            }
        };

        // 三、匿名類實現HelloWorld接口
        HelloWorld spanishGreeting = new HelloWorld() {
            String name = "mundo";
            public void greet() {
                greetSomeone("mundo");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hola, " + name);
            }
        };

        englishGreeting.greet();
        frenchGreeting.greetSomeone("Fred");
        spanishGreeting.greet();
    }

    public static void main(String... args) {
        HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }
}

匿名類表達式包含如下內部分:htm

  1. 操做符:new;
  2. 一個要實現的接口或要繼承的類,案例一中的匿名類實現了HellowWorld接口,案例二中的匿名內部類繼承了Animal父類;
  3. 一對括號,若是是匿名子類,與實例化普通類的語法相似,若是有構造參數,要帶上構造參數;若是是實現一個接口,只須要一對空括號便可;
  4. 一段被"{}"括起來類聲明主體;
  5. 末尾的";"號(由於匿名類的聲明是一個表達式,是語句的一部分,所以要以分號結尾)。

本部分參考JAVA匿名內部類(Anonymous Classes)對象


靜態內部類


靜態內部類是不須要依賴於外部類的,而且它不能使用外部類的非static成員變量或者方法,這個和普通靜態方法不能訪問非靜態方法或變量的原理同樣,具體能夠了解一下類的加載生命週期。

簡單地說就是靜態變量或方法是屬於類的,非靜態方法或變量是屬於對象的,jvm加載類的時候就爲類的靜態變量或方法分配內存的,而非靜態的須要等到要初始化對象時候纔給分配內存,而這個過程是動態的,也就是等到咱們何時想用,纔會有累的初始化過程。

簡單舉個例子:

class Outer {
	int a = 1
	static int a = 2;
    public Outter() {
         
    }
     
	/* 靜態內部類 */
    static class Inner {
        public Inner() {
             System.out.println(a); // 編譯會報錯
             System.out.println(b);

        }
    }
}

使用:

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

內部類簡單應用


爲何在 Java 中須要內部類?總結一下主要有如下四點內部類的使用場景和好處:

  • 1.每一個內部類都能獨立的繼承一個接口的實現,因此不管外部類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。內部類使得多繼承的解決方案變得完整。
  • 2.方便將存在必定邏輯關係的類組織在一塊兒,又能夠對外界隱藏。
  • 3.方便編寫事件驅動程序。
  • 4.方便編寫線程代碼。
相關文章
相關標籤/搜索