1. 程式人生 > >Java內部類之匿名內部類

Java內部類之匿名內部類

urn nat 看到了 math 通過 rri 內部 test mat

??我們都知道Java中可以使用內部類,將一個類的定義放在另一個類的定義的內部,這就是內部類,但是匿名內部類往往使我們摸不著頭腦,因為它並沒有特定的名稱,那麽該如何使用它呢?

定義一個匿名內部類

public interface Contents
{
    int value();
}

public class Test1
{
    private Contents contents()
    {
        return new Contents()
        {
            private int i = 11;
            @Override
            public int value()
            {
                return i;
            }
        };
    }

    public static void main(String[] args)
    {
        Test1 test = new Test1();
        Contents con = test.contents();
        System.out.println(con.value());
    }
}

??如上,我們就定義了一個匿名內部類,它實現了Contents接口,通過new表達式返回的引用被自動向上轉型為對Contents的引用,輸出結果就是11。這是一個最基本的匿名內部類,只是輸出了一個結果,下面我們來看看使用外部對象的匿名內部類。

使用帶參數的匿名內部類

public interface Destination
{
    String readLabel();
}

public class Test2
{
    private Destination destination(final String dest)
    {
        return new Destination()
        {
            private String label = dest;
            @Override
            public String readLabel()
            {
                return label;
            }
        };
    }

    public static void main(String[] args)
    {
        Test2 test2 = new Test2();
        Destination d = test2.destination("Wu Han");
        System.out.println(d.readLabel());
    }
}

??上面的匿名內部類傳入了一個參數,該匿名內部類使用了一個在外部定義的對象,那麽編譯器就要求其參數引用是final的。但是在JDK1.8中,就算沒有設置為final也沒有報錯。

對匿名內部類初始化

public interface Destination
{
    String readLabel();
}

public class Test3
{
    public Destination destination(final String dest, final float price)
    {
        return new Destination()
        {
            private int cost;
            {
                cost = Math.round(price);
                if(cost > 100)
                {
                    System.out.println("超出預支");
                }
            }

            private String label = dest;
            @Override
            public String readLabel()
            {
                return label;
            }
        };
    }

    public static void main(String[] args)
    {
        Test3 test3 = new Test3();
        Destination d3 = test3.destination("Wu Han", 101.1F);
        System.out.println(d3.readLabel());
    }
}

??如上,該匿名內部類中對cost進行了初始化,由於匿名內部類是沒有名稱的,所以初始化方法自然也是沒有名稱的了。

??在使用匿名內部類後,我們再使用工廠方法,該方法就可以變得十分簡潔易用。

??在最後說一下為什麽我們需要內部類,最吸引我們的一個原因是:每個內部類都能獨立地繼承一個(接口的)實現,所以無論外圍類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。在上面我們也看到了,使用匿名內部類,匿名內部類會直接實現接口,這在某些條件下會給我們帶來便捷性。

Java內部類之匿名內部類