內部類別


可以在類別中再定義類別,稱之為內部類別(Inner class),初學者暫時不會使用到內部類別,在這邊先簡單介紹語法,雖然會無聊一些,不過之後章節就會看到相關應用。

內部類別可以定義在類別區塊之中。例如以下程式片段建立了非靜態的內部類別:

class Some {
    class Other {
    }
}

雖然實務上很少看到接下來的寫法,不過要使用Some中的Other類別,必須先建立實例Some實例。例如:

Some s = new Some();
Some.Other o =  s.new Other();

內部類別也可以使用publicprotectedprivate宣告。例如:

class Some {
    private class Other {
    }
}

內部類別本身可以存取外部類別的成員,通常非靜態內部類別會宣告為private,這類內部類別是輔助類別中某些操作而設計,外部不用知道內部類別的存在。

內部類別也可以宣告為static。例如:

class Some {
    static class Other {
    }
}

一個被宣告為static的內部類別,通常是將外部類別當作名稱空間。你可以如下建立類別實例:

Some.Other o = new Some.Other();

被宣告為static的內部類別,雖然將外部類別當作名稱空間,但算是個獨立類別,它可以存取外部類別static成員,但不可存取外部類別非static成員。例如:

static內部類別不可存取外部類別非static成員


方法中也可以宣告類別,這通常是輔助方法中演算之用,方法外無法使用。例如:

class Some {
    public void doSome() {
        class Other {
        }
    }
}


實務上比較少看到在方法中定義具名的內部類別,倒很常看到方法中定義匿名內部類別(Anonymous inner class)並直接實例化,這跟類別繼承或介面實作有關,以下先看一下語法,細節留到談到繼承與介面時再作討論:

Object o = new Object() {
    public String toString() {
        return "無聊的語法示範而已";
    }
};

如果要稍微解釋一下,這個語法定義了一個沒有名稱的類別,它繼承Object類別,並重新定義(Override)了toString()方法,new表示實例化這個沒有名稱的類別。匿名類別語法本身,在某些場合有時有些囉嗦,JDK8提出了Lambda,有一部份目的是用來解決匿名類別語法囉嗦的問題,之後會再討論。