Java 接口语法细节

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)
}

猜你喜欢

转载自blog.csdn.net/juan200808/article/details/79974495