簡體   English   中英

接口方法可以有主體嗎?

[英]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 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM