1. 程式人生 > 其它 >java 匿名內部類 Anonymous Classes

java 匿名內部類 Anonymous Classes

1、簡介

匿名類是一個沒有類名的特殊內部類,也叫做匿名內部類。匿名內部類適合建立只需要使用一次的類。建立匿名內部類時須繼承一個已有的父類或實現一個介面。由於匿名類本身無名,因此也就不存在構造方法,而且匿名類不能重複使用。

具體可以參考

Anonymous Classes (The Java™ Tutorials > Learning the Java Language > Classes and Objects) (oracle.com)

2、定義匿名內部類

本地類是類宣告,而匿名類是表示式,這意味著可以在另一個表示式中定義該類。

匿名類本身沒有名字,在建立的時候用new語句的一部分來宣告。格式如下:

new父類名/介面名{
    //
}

例如:

package com.atguigu.java;

class HelloWorldAnonymousClasses {

    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }

    public void sayHello() {
        // 區域性類實現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 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(); spanishGreeting.greet(); } public static void main(String... args) { HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses(); myApp.sayHello(); } }

3、匿名內部類的語法

如前所述,匿名類是一種表示式。匿名類表示式的語法就像構造器的呼叫,但程式碼塊中包含類定義。

實現介面的匿名類

public class Test {
    public static void main(String[] args) {
        MyInterface mi = new MyInterface() {
            @Override
            public void say() {
                System.out.println("實現介面 hello");
            }
        };
        mi.say();
    }
}

interface MyInterface{
    void say();
}

繼承父類的匿名子類

public class Test {
    public static void main(String[] args) {
        // 多型:父類型別的變數指向子類型別的物件,呼叫方法的時候,是呼叫子類的實現(子類重寫、實現)
        MyClass mc = new MyClass("subclass"){
            public void hello(){
                System.out.println(name+",匿名子類問好");
            }
        };
        mc.hello();
    }
}

class MyClass{
    public String name;

    public MyClass(String name) {
        this.name = name;
    }
    public void hello(){
        System.out.println("hello");
    }
}

從上面可以看出,匿名類表示式包括以下內容:

  • 操作符 new

  • 要實現的介面名稱或要擴充套件的類的名稱。

  • 包含構造器引數的括號,就像正常的類例項建立表示式一樣。注意:當實現介面時,沒有構造器,因此使用空的括號,如果是匿名子類,與例項化普通類的語法類似。

  • 一個主體{}。

  • 匿名類的宣告是一個表示式,是語句的一部分,以分號結尾。

訪問作用域內的區域性變數、定義和訪問匿名內部類成員

與區域性類一樣,匿名類可以捕獲變數:它們具有相同的訪問封閉範圍的區域性變數:

  • 匿名類可以訪問其外部類的成員。

  • 匿名類無法訪問其外部類未宣告為或有效最終的本地變數。(注意:JDK1.8即使沒有用final修飾也可以訪問)

  • 與巢狀類一樣,匿名內部類定義的型別(如變數)會遮蔽其作用域範圍內的其他同名型別(變數)。

匿名內部類對其成員也有與本地類相同的限制:

  • 不能在匿名類中宣告靜態屬性和方法。

  • 匿名類可以具有靜態成員,前提是它們是常量。

請注意,您可以在匿名類中宣告以下事項:

  • 欄位

  • 額外方法(父介面、類中沒有的方法)

  • 例項初始化器

  • 內部類

但是不能在匿名類中宣告構造器。