简体   繁体   English

接口方法可以有主体吗?

[英]Can an interface method have a body?

I know that an interface is like a 100% pure abstract class.我知道接口就像一个 100% 纯抽象类。 So, it can't have method implementation in it.所以,它不能有方法实现。 But, I saw a strange code.但是,我看到了一个奇怪的代码。 Can anyone explain it?谁能解释一下?

Code Snippet:代码片段:

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

EDIT:编辑:

My IDE is Intellij Idea 13.1.我的 IDE 是 Intellij Idea 13.1。 The project SDK is java 7 <1.7.0_25>.项目 SDK 为 java 7 <1.7.0_25>。 The IDE is not showing any compiler error. IDE 未显示任何编译器错误。 But, When I compile the code at command line I am getting the following message.但是,当我在命令行编译代码时,我收到以下消息。

 Whoa.java:2: error: modifier static not allowed here public static void doStuff() { ^

From Java 8 you can define static methods in interfaces in addition to default methods.Java 8开始,除了默认方法之外,您还可以在接口中定义静态方法。

  • A static method is a method that is associated with the class in which it is defined rather than with any object.静态方法是与定义它的类相关联的方法,而不是与任何对象相关联的方法。 Every instance of the class shares its static methods.类的每个实例都共享其静态方法。

  • This makes it easier for you to organize helper methods in your libraries;这使您可以更轻松地在库中组织辅助方法; you can keep static methods specific to an interface in the same interface rather than in a separate class.您可以将特定于接口的静态方法保留在同一接口中而不是单独的类中。

  • The following example defines a static method that retrieves a ZoneId object corresponding to a time zone identifier;以下示例定义了一个静态方法,该方法检索与时区标识符对应的ZoneId对象; it uses the system default time zone if there is no ZoneId object corresponding to the given identifier.如果没有与给定标识符对应的ZoneId对象,则使用系统默认时区。 (As a result, you can simplify the method getZonedDateTime ) (因此,您可以简化方法getZonedDateTime

Here is code :这是代码:

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

See also也可以看看

This is only possible in Java 8. In the Java 7 Language Specification §9.4 , it explicitly states:这仅在 Java 8 中才有可能。在Java 7语言规范 §9.4中,它明确指出:

It is a compile-time error if a method declared in an interface is declared static, because static methods cannot be abstract.如果在接口中声明的方法被声明为静态,这是编译时错误,因为静态方法不能是抽象的。

So in Java 7, static methods in interfaces cannot exist.所以在 Java 7 中,接口中的静态方法不能存在。

If you go to the Java 8 Language Specification §9.4.3 , you can see that it says:如果您转到Java 8语言规范 §9.4.3 ,您会看到它说:

A static method also has a block body, which provides the implementation of the method.静态方法也有一个块体,它提供了方法的实现。

So it explicitly states that in Java 8, they can exist.所以它明确指出在 Java 8 中,它们可以存在。

I even tried to run your exact code in Java 1.7.0_45, but it gave me the error "modifier static not allowed here".我什至尝试在 Java 1.7.0_45 中运行您的确切代码,但它给了我错误“此处不允许使用修饰符静态”。


Here is a quote directly from the Java 8 tutorial, Default Methods (Learning the Java Language > Interfaces and Inheritance) :这是直接来自 Java 8教程Default Methods (Learning the Java Language > Interfaces and Inheritance)的引用:

Static Methods静态方法

In addition to default methods, you can define static methods in interfaces.除了默认方法外,您还可以在接口中定义静态方法 (A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.) This makes it easier for you to organize helper methods in your libraries; (静态方法是与定义它的类相关联的方法,而不是与任何对象相关联。类的每个实例都共享其静态方法。)这使您可以更轻松地在库中组织辅助方法; you can keep static methods specific to an interface in the same interface rather than in a separate class.您可以将特定于接口的静态方法保留在同一接口中而不是单独的类中。 The following example defines a static method that retrieves a ZoneId object corresponding to a time zone identifier;以下示例定义了一个静态方法,该方法检索与时区标识符对应的ZoneId对象; it uses the system default time zone if there is no ZoneId object corresponding to the given identifier.如果没有与给定标识符对应的ZoneId对象,则使用系统默认时区。 (As a result, you can simplify the method getZonedDateTime ): (因此,您可以简化方法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)); } }

Like static methods in classes, you specify that a method definition in an interface is a static method with the static keyword at the beginning of the method signature.与类中的静态方法一样,您可以将接口中的方法定义指定为静态方法,并在方法签名的开头使用static关键字。 All method declarations in an interface, including static methods, are implicitly public , so you can omit the public modifier.接口中的所有方法声明,包括静态方法,都是隐式的public ,因此您可以省略public修饰符。

For java version 7 or below , similar functionally you can achieve using nested class declared within interface body.对于java版本7 或更低版本,您可以使用在接口主体中声明的嵌套类来实现类似的功能。 and this nested class implements outer interface.这个嵌套类实现了外部接口。

Example:例子:

interface I1{
    public void doSmth();

    class DefaultRealizationClass implements  I1{

        @Override
        public void doSmth() {
           System.out.println("default realization");
        }
    }
}

How do we use it in our code?我们如何在代码中使用它?

class MyClass implements I1{

    @Override
    public void doSmth() {
         new I1.DefaultRealizationClass().doSmth();
    }   
}

Therefore default implementation encapsulated within interface.因此,默认实现封装在接口中。

Over the period java interfaces have evolved a lot and Java 8 completely changed the way interfaces were presumed.在此期间,Java 接口已经发展了很多,Java 8 完全改变了接口的假定方式。

Coming to question, yes we can have a method body in the interface.提出问题,是的,我们可以在接口中有一个方法体。

whereas in java 8 we can have a method body in a static method and in the default method like the below example.而在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();
    }
}
}

we can also have the private method in the interfaces from java 9 onwards.从 java 9 开始,我们也可以在接口中使用私有方法 like below code compiles well in java 9 and above versions but fails in java 8 and below如下代码在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();   
     } 
}   
 

References: https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html [https://www.quora.com/profile/Rajat-Singh-187/Private-Method-in-the-Java-Interface]参考: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM