簡體   English   中英

Java中default關鍵字的目的是什么?

[英]What is the purpose of the default keyword in Java?

Java中的接口類似於類,但是接口的主體只能包含抽象方法final字段(常量)。

最近,我看到一個問題,看起來像這樣

interface AnInterface {
    public default void myMethod() {
        System.out.println("D");
    }
}

根據接口定義, 允許使用抽象方法 為什么它允許我編譯以上代碼? default關鍵字是什么?

另一方面,當我嘗試編寫以下代碼時,它說modifier default not allowed here

default class MyClass{

}

代替

class MyClass {

}

誰能告訴我default關鍵字的用途? 只能在接口內部使用嗎? 它與default (無訪問修飾符)有何不同?

這是Java 8中的一項新功能,它允許interface提供實現。 在Java 8 JLS-13.5.6中描述 讀取(部分) 接口方法聲明

添加default方法,或將方法從abstract更改為default ,都不會破壞與現有二進制文件的兼容性,但如果現有二進制文件嘗試調用該方法,則可能會導致IncompatibleClassChangeError 如果限定類型T是兩個接口IJ的子類型,則該錯誤發生,其中IJ聲明具有相同簽名和結果的default方法,而IJ都不是另一個子接口。

JDK 8的新增功能說(部分)

默認方法允許將新功能添加到庫的接口,並確保與為這些接口的較早版本編寫的代碼二進制兼容。

默認方法已添加到Java 8,主要是為了支持lambda表達式。 設計人員(我認為很明智)決定使用lambdas語法來創建接口的匿名實現。 但是給定的lambda只能實現一個方法,因此它們將被限制為具有一個方法的接口,這將是一個非常嚴格的限制。 相反,添加了默認方法以允許使用更復雜的接口。

如果需要說服lambdas引入default的說法令人信服,請注意,Mark Reinhold在2009年提出的關於Lambda項目的稻草人提案中提到,“擴展方法”是為支持lambdas而添加的強制性功能。

這是一個演示概念的示例:

interface Operator {
    int operate(int n);
    default int inverse(int n) {
        return -operate(n);
    }
}

public int applyInverse(int n, Operator operator) {
    return operator.inverse(n);
}

applyInverse(3, n -> n * n + 7);

我意識到,我非常想做,但應該說明default如何支持lambda。 因為inverse是默認值,所以如果需要,可以由實現類輕松覆蓋。

Java 8中引入了一個新概念,稱為默認方法。 默認方法是具有一些默認實現的那些方法,它們有助於在不破壞現有代碼的情況下擴展接口。 讓我們看一個例子:

 public interface SimpleInterface {
    public void doSomeWork();

    //A default method in the interface created using "default" keyword

    default public void doSomeOtherWork(){

    System.out.println("DoSomeOtherWork implementation in the interface");
       }
    }

 class SimpleInterfaceImpl implements SimpleInterface{

  @Override
  public void doSomeWork() {
  System.out.println("Do Some Work implementation in the class");
   }

 /*
  * Not required to override to provide an implementation
  * for doSomeOtherWork.
  */

 public static void main(String[] args) {
   SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
   simpObj.doSomeWork();
   simpObj.doSomeOtherWork();
      }
   }

輸出為:

在課堂上完成一些工作
接口中的DoSomeOtherWork實現

在其他答案中被忽略的是它在注釋中的作用。 早在Java 1.5之前, default關鍵字便是為注釋字段提供默認值的一種手段。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Processor {
    String value() default "AMD";
}

Java 8的引入使它的使用超載 ,從而允許人們在接口中定義默認方法。

其他一些被忽略的問題:聲明default class MyClass {}無效的原因是由於類的聲明方式。 語言中沒有規定允許該關鍵字出現在該位置。 不過,它確實出現在接口方法聲明中

新的Java 8功能( Default Methods )允許接口在使用default關鍵字標記時提供實現。

例如:

interface Test {
    default double getAvg(int avg) {
        return avg;
    }
}
class Tester implements Test{
 //compiles just fine
}

接口測試使用default關鍵字,該關鍵字允許接口提供該方法的默認實現,而無需在使用該接口的類中實現這些方法。

向后兼容:假設您的接口由數百個類實現,則修改該接口將迫使所有用戶實現新添加的方法,即使對於實現該接口的許多其他類而言也不是必需的。

事實與限制:

1-只能在接口中聲明,而不能在類或抽象類中聲明。

2-必須提供身體

3-不假定它是公共的或抽象的,而不是接口中使用的其他常規方法。

Java™Tutorials中找到了很好的解釋,部分解釋如下:

考慮一個涉及計算機控制汽車制造商的示例,這些制造商發布了行業標准界面,這些界面描述了可以調用哪些方法來操作其汽車。 如果那些由計算機控制的汽車制造商在其汽車中增加了新功能,例如飛行,該怎么辦? 這些制造商將需要指定新的方法,以使其他公司(例如電子制導儀器制造商)能夠將其軟件適配於飛行汽車。 這些汽車制造商將在哪里宣布這些與飛行有關的新方法? 如果他們將它們添加到其原始接口,則實現了這些接口的程序員將不得不重寫其實現。 如果他們將它們添加為靜態方法,那么程序員將把它們視為實用程序方法,而不是必不可少的核心方法。

默認方法使您可以向庫的接口添加新功能,並確保與為這些接口的較早版本編寫的代碼二進制兼容。

默認方法使您可以向應用程序界面添加新功能。 它也可以用於具有多重繼承 除了默認方法外,您還可以在接口中定義靜態方法。 這使您更輕松地組織幫助程序方法

接口中的默認方法使我們能夠添加新功能而不會破壞舊代碼。

在Java 8之前,如果將新方法添加到接口,則該接口的所有實現類都必須重寫該新方法,即使它們沒有使用新功能。

使用Java 8,我們可以在方法實現之前使用default關鍵字為新方法添加默認實現。

即使使用匿名類或函數接口,如果我們看到某些代碼是可重用的,並且我們不想在代碼中的任何地方定義相同的邏輯,則可以編寫這些代碼的默認實現並重用它們。

public interface YourInterface {
    public void doSomeWork();

    //A default method in the interface created using "default" keyword
    default public void doSomeOtherWork(){

    System.out.println("DoSomeOtherWork implementation in the interface");
       }
    }

    class SimpleInterfaceImpl implements YourInterface{

     /*
     * Not required to override to provide an implementation
     * for doSomeOtherWork.
     */
      @Override
      public void doSomeWork() {
  System.out.println("Do Some Work implementation in the class");
   }

 /*
  * Main method
  */
 public static void main(String[] args) {
   SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
   simpObj.doSomeWork();
   simpObj.doSomeOtherWork();
      }
   }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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