接口方法可以有一个体?

67 java interface default-implementation java-8

我知道界面就像100%纯抽象类.所以,它不能有方法实现.但是,我看到了一个奇怪的代码.有人能解释一下吗?

代码片段:

 interface Whoa {
        public static void doStuff() {
            System.out.println("This is not default implementation");
        }
 }
Run Code Online (Sandbox Code Playgroud)

编辑:

我的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() {
                       ^
Run Code Online (Sandbox Code Playgroud)

Ani*_*rni 93

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));
   }    
}
Run Code Online (Sandbox Code Playgroud)

也可以看看

  • 也是方法的默认实现. (3认同)
  • 这似乎真的模糊了接口和抽象类之间的界限。 (3认同)
  • 您的IDE是否使用代码符合8?这应该__not__用7及以下编译.这是一篇[好文章](http://www.techempower.com/blog/2013/03/26/everything-about-java-8/). (2认同)

The*_*Hat 19

这只能在Java 8中实现.在Java 7语言规范§9.4中,它明确指出:

如果在接口中声明的方法声明为static,则这是一个编译时错误,因为静态方法不能是抽象的.

所以在Java 7中,接口中的静态方法不可能存在.

如果你转到Java 8语言规范§9.4.3,你可以看到它说:

静态方法还有一个块体,它提供了该方法的实现.

因此它明确指出在Java 8中它们可以存在.

我甚至试图在Java 1.7.0_45中运行您的确切代码,但它给了我错误"modifier static not allowed here".


以下是Java 8教程中的引用,默认方法(学习Java语言>接口和继承):

静态方法

除了默认方法,您还可以在接口中定义静态方法.(静态方法是一种与定义它的类相关联的方法,而不是与任何对象相关联.该类的每个实例都共享其静态方法.)这使您可以更轻松地在库中组织辅助方法; 您可以在同一个接口中保留特定于接口的静态方法,而不是在单独的类中.以下示例定义了一个静态方法,用于检索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));
    }    
}
Run Code Online (Sandbox Code Playgroud)

与类中的静态方法一样,您可以指定接口中的方法定义是静态方法,并static在方法签名的开头使用关键字.接口中的所有方法声明(包括静态方法)都是隐式的public,因此您可以省略public修饰符.


gst*_*low 13

对于java版本7或更低版本,在功能上类似,您可以使用在接口体内声明的嵌套类来实现.这个嵌套类实现了外部接口.

例:

interface I1{
    public void doSmth();

    class DefaultRealizationClass implements  I1{

        @Override
        public void doSmth() {
           System.out.println("default realization");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我们如何在代码中使用它?

class MyClass implements I1{

    @Override
    public void doSmth() {
         new I1.DefaultRealizationClass().doSmth();
    }   
}
Run Code Online (Sandbox Code Playgroud)

因此默认实现封装在接口中.