[英]Can an interface method have a body?
我知道接口就像一个 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));
}
}
对于 Java 8 中所有有趣的事情,请阅读关于 Java 8 的一切
这仅在 Java 8 中才有可能。在Java 7语言规范 §9.4中,它明确指出:
如果在接口中声明的方法被声明为静态,这是编译时错误,因为静态方法不能是抽象的。
所以在 Java 7 中,接口中的静态方法不能存在。
如果您转到Java 8语言规范 §9.4.3 ,您会看到它说:
静态方法也有一个块体,它提供了方法的实现。
所以它明确指出在 Java 8 中,它们可以存在。
我什至尝试在 Java 1.7.0_45 中运行您的确切代码,但它给了我错误“此处不允许使用修饰符静态”。
这是直接来自 Java 8教程Default Methods (Learning the Java Language > Interfaces and 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
关键字。 接口中的所有方法声明,包括静态方法,都是隐式的public
,因此您可以省略public
修饰符。
对于java版本7 或更低版本,您可以使用在接口主体中声明的嵌套类来实现类似的功能。 这个嵌套类实现了外部接口。
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();
}
}
因此,默认实现封装在接口中。
在此期间,Java 接口已经发展了很多,Java 8 完全改变了接口的假定方式。
提出问题,是的,我们可以在接口中有一个方法体。
而在java 8中,我们可以在静态方法和默认方法中拥有方法体,如下例所示。
interface CheckMyEvolution{
default void whatsNew() {
System.out.print("Hello there!Check my Evolution");
}
static 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();
}
}
}
从 java 9 开始,我们也可以在接口中使用私有方法。 如下代码在java 9及以上版本中编译良好,但在 java 8 及以下版本中失败
interface CheckMyEvolution{
default void whatsNew() {
checkIt();
}
// Private method
private void checkIt() {
System.out.println("Hello there! I can have private method now. Make sure you are using JDK 9 or Above.");
}
}
public class CheckMyEvolutionImpl implements CheckMyEvolution{
public static void main(String[] args) {
CheckMyEvolution evolution= new CheckMyEvolutionImpl();
evolution.whatsNew();
}
}
参考: https ://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html [https://www.quora.com/profile/Rajat-Singh-187/Private-Method-in-the- Java接口]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.