一个接口方法可以有一个正文?
我知道一个接口就像是一个100%纯粹的抽象类。 所以,它不能有方法的实现。 但是,我看到一个奇怪的代码。 任何人都可以解释吗?
代码片段:
interface Whoa { public static void doStuff() { System.out.println("This is not default implementation"); } }
编辑:
我的IDE是Intellij Idea 13.1。 项目SDK是java 7 <1.7.0_25>。 IDE没有显示任何编译器错误。 但是,当我在命令行编译代码时,我收到以下消息。
Whoa.java:2: error: modifier static not allowed here public static void doStuff() { ^
从Java 8开始 ,除了默认方法之外,您还可以在接口中定义静态方法。
-
静态方法是一种与其定义的类关联的方法,而不是任何对象。 每个类的实例共享其静态方法。
-
这使您更容易在您的库中组织帮助器方法; 您可以在同一个接口中保留特定于接口的静态方法,而不是在单独的类中。
-
以下示例定义了一个静态方法,用于检索与时区标识符对应的
ZoneId
对象; 如果没有对应于给定标识符的ZoneId
对象,则使用系统默认时区。 (因此,您可以简化getZonedDateTime
方法)
这是代码:
public interface TimeClient { // ... static public ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { System.err.println("Invalid time zone: " + zoneString +"; using default time zone instead."); return ZoneId.systemDefault(); } } default public ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } }
也可以看看
-
Oracle文档的接口方法
-
对于Java 8中所有有趣的东西,请阅读关于Java 8的所有内容
这只能在Java 8中实现。在Java 7 Language Specification§9.4中 ,它明确指出:
如果在接口中声明的方法被声明为静态,那么这是一个编译时错误,因为静态方法不能是抽象的。
所以在Java 7中,接口中的静态方法是不存在的。
如果你转到Java 8语言规范§9.4.3 ,你可以看到它说:
一个静态方法也有一个块体,它提供了方法的实现。
所以它明确指出,在Java 8中,它们可以存在。
我甚至试图在Java 1.7.0_45中运行你的确切的代码,但它给了我错误“修改器静态不允许在这里”。
这里直接引用了Java 8教程中的默认方法(学习Java语言>接口和inheritance) :
静态方法
除了默认方法之外,您还可以在接口中定义静态方法 。 (静态方法是一个与定义它的类相关联的方法,而不是与任何对象相关联的类的每个实例共享其静态方法)这使得您可以更轻松地在库中组织帮助器方法; 您可以在同一个接口中保留特定于接口的静态方法,而不是在单独的类中。 以下示例定义了一个静态方法,用于检索与时区标识符对应的
ZoneId
对象; 如果没有对应于给定标识符的ZoneId
对象,则使用系统默认时区。 (因此,您可以简化getZonedDateTime
方法):public interface TimeClient { // ... static public ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { System.err.println("Invalid time zone: " + zoneString + "; using default time zone instead."); return ZoneId.systemDefault(); } } default public ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } }
与类中的静态方法类似,您可以指定接口中的方法定义是在方法签名开始处使用
static
关键字的static
方法。 接口中的所有方法声明(包括静态方法)都是隐式public
,所以可以省略public
修饰符。
对于Java版本7或更低版本,类似的function可以使用在接口体内声明的嵌套类来实现。 而这个嵌套类实现了外部接口。
例:
interface I1{ public void doSmth(); class DefaultRealizationClass implements I1{ @Override public void doSmth() { System.out.println("default realization"); } } }
我们如何在代码中使用它?
class MyClass implements I1{ @Override public void doSmth() { new I1.DefaultRealizationClass().doSmth(); } }
因此默认实现封装在接口中。