Java 接口語法細節
Java 接口語法細節
1、接口的默認
在Java中,可使用 interface來定義抽象的行為外觀,如接口中的方法可聲明為 public abstract。例如:
public interface Swimmer{
public abstract void swim();
}
- 1
- 2
- 3
接口中的方法沒有操作時,一定得是公開且抽象,為了方便,你也可以省略public abstract。
public interface Swimmer{
void swim();
}
- 1
- 2
- 3
swim()默認就是 public abstract。
編譯程序會自動幫你加上 public abstract。由於默認一定是 public,因此:
interface Action{
void execute();
}
class Some implements Action{
void execute(){
System.out.printf("gggggg");
}
}
public class Main{
public static void main(String[] args) {
Action action=new Some();
action.execute();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
“請問執行結果為何?”這個問題本身就是個陷阱,根本無法編譯成功,因為 Action中定義的 execute()其實默認為 public abstract,而some類在操作execute()方法時,沒有撰寫 public,因此就是默認為包權限,這等於是將 Action中 public的方法縮小為包權限,所以編譯失敗了。必須將some類的 execute()設為 public才可通過編譯。
從JDK8開始, interface中的方法可以有限制地操作,這是為了支持 Lambda而擴充的新特性。
在 interface中,可以定義常數。例如:
package hello;
public interface Action {
public static final int STOP=0;
public static final int RIGHT=0;
public static final int LEFT=0;
public static final int UP=0;
public static final int DOWN=0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
這類常數稱為枚舉常數,讓程序看的清楚:
public interface Action {
public static final int STOP=0;
public static final int RIGHT=1;
public static final int LEFT=2;
public static final int UP=3;
public static final int DOWN=4;
}
class game {
public static void main(String[] args) {
}
public static void play(int action) {
switch(action) {
case Action .STOP:
out.println("停止播放動畫");
break;
case Action .DOWN:
out.println("向下播放");
break;
........
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
這比直接用switch判斷0、1、2、3、4看的清楚多了。在interface中只能定義枚舉常數,所以可以:
int STOP=0;
int RIGHT=1;
int LEFT=2;
int UP=3;
int DOWN=4;
- 1
- 2
- 3
- 4
- 5
編譯程序會自動展開。當然在類中定義枚舉常數也可以,但是不能縮寫。
JDK5後新增enum語法定義枚舉常數:
public enum Action{
STOP,UP,DOWN,LEFT,RIGHT
}
- 1
- 2
- 3
反編譯可以看到,範例的enum定義的 Action實際上是個類,而
enum中列舉的STOP、 RIGHT、LEPT、UP、DOWN常數,實際上是 public static final,且為Action實例,你無法撰寫程序直接實例化 Action,因為構造函數權限設定為 private,只有 Action類中才可以實例化。那麽可以使用這個 Action用它來聲明類型。例如:
public static void play(Action action) {
switch(action) {
case Action .STOP:
out.println("停止播放動畫");
break;
case Action .DOWN:
out.println("向下播放");
break;
........
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
public static void play(Action action)
在這個範例中,play()方法中的 action參數聲明為 Action類型,所以只接受 Action實例,也就是只有 Action.STOP、 Action. RIGHT、 Action.LEFT、 Action.UP、 Action.DOWN可傳入。不像剛剛的play()方法,可以傳入任何int值,case比較也只能列舉 Action實例,所以不用像前面範例,必須使用 default在執行時期檢查,編譯程序在編譯時期會進行類型檢查。
類可以操作兩個以上接口,如果兩個接口中定義了相同方法,如果表示是同一個方法,可以提升為父接口,這兩個接口再繼承該接口:
public interface Swimmer {
void a();
}
public interface Action1 extends Swimmer {
void b();
}
public interface Action2 extends Swimmer{
void c();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
匿名內部類
在撰寫Java程序時,經常會有臨時繼承某個類或操作某個接口並建立實例的需求。由於這類子類或接口操作類只使用一次,不需要為這些類定義名稱,這時可以使用匿名內部類( Anonymous Inner Class)來解決這個需求。匿名內部類的語法為:
new 父類()|接口(){
//類本體操作
}
Object obj=new Object() {
@Override
public String toString() {
return "返利";
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
繼承object重新定義toString方法。如果是操作接口如Some接口定義抽象方法doSome建立匿名內部類:
Some some = new Some(){
public void doSome(){
//執行語句
};
};
- 1
- 2
- 3
- 4
- 5
JDK8以後接口只有一個方法、可以這樣創建:
Some some = () ->{
//執行語句(Lambda)
}
Java 接口語法細節