可以在接口中声明三种类型的方法:
在Java 8之前,只能在接口中声明抽象方法。 修饰符static
和default
用于分别声明静态和默认方法。
不使用static
和default
修饰符就是方法抽象。
以下是具有所有三种类型方法的接口的示例:
interface AnInterface { // An abstract method int m1(); // A static method static int m2() { // The method implementation goes here } // A default method default int m3() { // The method implementation goes here } }
接口中的所有方法声明都是隐式抽象和公开的,除非它们声明为static
或default
。接口中的抽象方法没有实现。抽象方法的主体总是由分号表示,而不是一对大括号。
下面的代码声明一个名为Player
的接口:
public interface Player { public abstract void play(); public abstract void stop(); public abstract void forward(); public abstract void rewind(); }
Player
接口是音频/视频播放器的规范。真实的播放器,例如DVD
播放器,将通过实现 Player
接口的所有四个方法来提供规范的具体实现。
在接口中使用 abstract
和 public
关键字声明方法中是多余的。上面的Player
接口的声明可以改写如下,而不改变其含义:
public interface Player { void play(); void stop(); void forward(); void rewind(); }
接口中的抽象方法声明可以包括参数,返回类型和throws
子句。
public interface NewPlayer { boolean play(int account) throws AccountNotFoundException; boolean stop(double amount); boolean forward(double amount) throws InsufficientBalanceException; double rewind(); }
接口的抽象方法由实现接口的类来实现,类重写它们以提供方法并实现。接口中的抽象方法不能声明为final
。
类可以重写声明接口的方法为final
,指示子类不能覆盖该方法。
从Java 8,我们可以在接口中创建静态方法。静态方法包含静态修饰符- static
,并且是隐式公开的。可以重新定义Walkable
接口以包括letThemWalk()
方法。
interface Walkable { // An abstract method void walk(); // A static convenience method public static void letThemWalk(Walkable[] list) { for (int i = 0; i < list.length; i++) { list[i].walk(); } } }
可以使用点表示法使用接口的静态方法。如下代码 -
<interface-name>.<static-method>
与类中的静态方法不同,接口中的静态方法不能通过实现类或子接口来继承。从另一个接口继承的接口称为子接口。 只有一种方法来调用接口的静态方法:使用接口名称。例如:
必须使用MyInterface.myStaticMethod()
调用接口MyInterface
的静态方法myStaticMethod()
。
可以使用方法的非限定名称myStaticMethod()
来调用它,这仅在接口的主体中,或者当使用静态import
语句导入方法时可这样使用。
接口中的默认方法使用修辞符-default
来声明。默认方法是在Java 8中添加新功能。默认方法为实现接口的类提供了一个默认实现,但不覆盖默认方法。
假设,有以下的一个接口。
interface Shape{ void setX(double x); void setY(double y); double getX(); double getY(); }
下面的代码显示了 Circle
类实现了 Shape
接口。
class Circle implements Movable { private double x; private double y; public Circle() { } public Circle(double x, double y) { this.x = x; this.y = y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } public double getX() { return x; } public double getY() { return y; } public String toString() { return "Circle(" + x + ", " + y + ")"; } }
如果向Shape
添加一个新方法如下。
interface Shape { void setX(double x); void setY(double y); double getX(); double getY(); void move(double deltaX, double deltaY); }
在Java 8之前,新方法move()
是一个抽象方法。 所有实现Shape
接口的类都必须提供这个新方法的实现。
实现Shape
接口的Pen
类将不能通过编译,除非将新方法添加实现到这些类中。在Java 8之前,在将接口分配给公共接口之后,在中断实现接口方法代码的情况下,向接口添加方法是不可能的。
所以,引入了Java接口默认方法这个解决方案。可以将默认方法添加到现有接口,并为该方法提供默认实现而不用在实现接口的类中实现这个默认方法。
所有实现接口的类都将继承默认实现。类可以选择覆盖默认实现或使用方法的默认实现。
默认方法使用关键字default
声明。 默认方法不能声明为abstract
或static
。 它必须提供一个实现。 否则将在编译时发生错误。
以下代码使用默认方法更改Shape
接口。
interface Movable { void setX(double x); void setY(double y); double getX(); double getY(); // 一个默认的方法 default void move(double deltaX, double deltaY) { double newX = getX() + deltaX; double newY = getY() + deltaY; setX(newX); setY(newY); } }
以下项目列出了类方法和接口默认方法之间的相似点和差异。
this
。 关键字this
是调用方法的对象的引用。throws
子句。参考以下一个具有嵌套类和常量字段的Task
接口。
interface Task { class EmptyTask implements Task { private EmptyTask() { } public void runJob() { System.out.println("Empty..."); } } // A constant field Task EMPTY_JOB = new EmptyTask(); void runJob(); } public class Main { public static void main(String[] args) { submitJob(Task.EMPTY_JOB); } public static void submitJob(Task job) { job.runJob(); } }
Java接口方法 # Java_interface_Methods