接口方法可以有一个体?

时间:2014-03-28 13:02:47

标签: java interface java-8 default-implementation

我知道界面就像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() {
                       ^

3 个答案:

答案 0 :(得分:90)

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

另见

答案 1 :(得分:19)

这只能在Java 8中实现。在Java 7 Language Specification §9.4中,它明确指出:

  

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

因此在Java 7中,接口中的静态方法不能存在。

如果你转到Java 8 Language Specification §9.4.3,你会看到它说:

  

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

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

我甚至尝试在Java 1.7.0_45中运行您的确切代码,但它给了我错误"修饰符静态不允许在这里"。


以下引用直接来自Java 8 教程,Default Methods (Learning the Java Language > Interfaces and Inheritance)

  

静态方法

     

除了默认方法,您还可以定义static methods   接口。 (静态方法是一种与之相关的方法   定义它而不是任何对象的类。一切   该类的实例共享其静态方法。)这使它更容易   为您组织库中的辅助方法;你可以保持   相反,特定于接口的静态方法   而不是在一个单独的类。以下示例定义静态   检索与时间对应的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修饰符。

答案 2 :(得分:13)

对于 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();
    }   
}

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