1. 前言
匿名內部類,有的朋友覺得不好理解,其實顧名思義就可以了。
匿名,表示這個類沒有名稱。
內部類,表示不是一個獨立的類,而是在一個類或方法內部的類。
2. 傳統方式
首先我們需要面向接口編程,這個是很自然,面向接口編程提供了對現實社會模型的抽象,可以提供更高的靈活性。
傳統方式下,我們通過類來實現接口,然後通過類對象來進行調用。
2.1 定義接口
舉個例子,打仗需要使用武器,武器需要準備,然後發射,所以定義武器接口:
/**
* 武器接口
*/
public interface Weapon {
/**
* 準備
*/
public void prepare();
/**
* 發射
*/
public void launch();
}
2.2 使用接口
當軍隊發起戰役時,需要使用武器進行戰鬥:
/**
* 戰役類
*/
public class Battle {
/**
* 使用武器進行戰鬥
*/
public void fight(Weapon w) {
w.prepare();
w.launch();
}
}
2.3 使用實現類
OK,此時如果是現代軍隊,武器種類很多,有坦克、大炮、航母、飛機等等,我們可以實現各種武器,然後進行戰鬥。
如下示例,就是最常用的,定義類實現接口,然後通過類對象進行調用。
/**
* 坦克武器
*/
public class Tank implements Weapon {
@Override
public void prepare() {
System.out.println("坦克裝填炮彈");
}
@Override
public void launch() {
System.out.println("坦克開火");
}
public static void main(String[] args) {
Battle battle=new Battle();
Tank tank=new Tank();
battle.fight(tank);
}
}
3. 使用匿名內部類
但是如果接口的實現類只使用一次,我們來定義類,並通過類對象來進行操作是比較繁瑣的。
具體到上面的場景中,就是說根本沒啥高科技武器,就是一羣原始人用扔石頭戰鬥。此時如果單獨定義一個石頭類意義不大,而且比較麻煩,所以可以直接用匿名內部類解決。
/**
* 戰役類
*/
public class Battle {
/**
* 使用武器進行戰鬥
*/
public void fight(Weapon w) {
w.prepare();
w.launch();
}
public static void main(String[] args) {
Battle battle = new Battle();
// 使用匿名內部類
battle.fight(new Weapon() {
@Override
public void prepare() {
System.out.println("拿起石頭");
}
@Override
public void launch() {
System.out.println("扔石頭");
}
});
}
}
注意在上面的例子中,我們並未定義Weapon接口的實現類,而是直接創建了Weapon類型的對象,同時定義了一個實現Weapon接口的匿名內部類。
注意匿名內部類同時定義了類的方法,而且接着就生成了該類型的對象,然後接着就調用了,非常簡潔而方便。
如果上面的例子還不好理解的話,可以參考:
/**
* 戰役類
*/
public class Battle {
/**
* 使用武器進行戰鬥
*/
public void fight(Weapon w) {
w.prepare();
w.launch();
}
public static void main(String[] args) {
Battle battle = new Battle();
// 使用匿名內部類
Weapon weapon = new Weapon() {
@Override
public void prepare() {
System.out.println("拿起石頭");
}
@Override
public void launch() {
System.out.println("扔石頭");
}
};
battle.fight(weapon);
}
}
4. 使用場景
大部分情況下,還是使用接口–實現類這樣的結構。
如果僅僅是在調用時臨時使用,可以不定義實現類,藉助匿名內部類來快速開發。