risposta-alla-domanda-sullo-sviluppo-web-bd.com

Qual è lo scopo della parola chiave predefinita in Java?

Un'interfaccia in Java è simile a una classe, ma il corpo di un'interfaccia può includere solo metodi astratti e final campi (costanti).

Di recente, ho visto una domanda, che assomiglia a questa

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

Secondo la definizione dell'interfaccia, sono ammessi solo metodi astratti. Perché mi permette di compilare il codice sopra? Che cos'è la parola chiave default?

D'altra parte, quando stavo provando a scrivere sotto il codice, allora dice modifier default not allowed here

default class MyClass{

}

invece di

class MyClass {

}

Qualcuno può dirmi lo scopo della parola chiave default? È consentito solo all'interno di un'interfaccia? In che cosa differisce da default (nessun modificatore di accesso)?

76
Ravi

È una nuova funzionalità in Java 8 che consente a interface di fornire un'implementazione. Descritto in Java 8 JLS-13.5 .6 Dichiarazioni sui metodi di interfaccia che legge (in parte)

L'aggiunta di un metodo default o la modifica di un metodo da abstract a default non interrompono la compatibilità con i binari preesistenti, ma possono causare un IncompatibleClassChangeError se un binario preesistente tenta di invocare il metodo. Questo errore si verifica se il tipo di qualifica, T, è un sottotipo di due interfacce, I e J, dove entrambi I e J dichiara un metodo default con la stessa firma e lo stesso risultato e né IJ sono una sottointerfaccia dell'altro.

Novità di JDK 8 dice (in parte)

I metodi predefiniti consentono l'aggiunta di nuove funzionalità alle interfacce delle librerie e garantiscono la compatibilità binaria con il codice scritto per le versioni precedenti di tali interfacce.

59
Elliott Frisch

I metodi predefiniti sono stati aggiunti a Java 8 principalmente per supportare le espressioni lambda. I progettisti (abilmente, a mio avviso) hanno deciso di creare la sintassi lambdas per la creazione di implementazioni anonime di un'interfaccia. Ma dato lambdas può solo implementare un singolo metodo sarebbero limitati alle interfacce con un singolo metodo che sarebbe una restrizione piuttosto severa, invece sono stati aggiunti metodi predefiniti per consentire l'uso di interfacce più complesse.

Se hai bisogno di convincere l'affermazione che default è stato introdotto a causa di lambdas, nota che proposta di paglia del Progetto Lambda, di Mark Reinhold, nel 2009, menziona "Metodi di estensione" come funzionalità obbligatoria da aggiungere per supportare lambdas.

Ecco un esempio che dimostra il concetto:

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

Mi rendo conto molto, ma dovrei illustrare come default supporti lambdas. Poiché inverse è un valore predefinito, può essere facilmente sostituito da una classe di implementazione, se necessario.

21
sprinter

Un nuovo concetto è stato introdotto in Java 8 chiamato metodi predefiniti. I metodi predefiniti sono quei metodi che hanno un'implementazione predefinita e aiutano a far evolvere le interfacce senza rompere il codice esistente. Vediamo un esempio:

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

e l'output è:

Implementazione di alcuni lavori in classe
Implementazione di DoSomeOtherWork nell'interfaccia

13
Saurabh Gaur

Qualcosa che è stato trascurato nelle altre risposte è stato il suo ruolo nelle annotazioni. A partire da Java 1.5, la parola chiave default è nata come mezzo per fornire un valore predefinito per un campo di annotazione.

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

L'utilizzo è stato sovraccarico con l'introduzione di Java 8 per consentire di definire un metodo predefinito nelle interfacce.

Qualcos'altro che è stato trascurato: il motivo per cui la dichiarazione default class MyClass {} non valido è dovuto al modo in cui le classi sono dichiarate affatto . Non esiste alcuna disposizione nella lingua che consenta che quella parola chiave venga visualizzata lì. Tuttavia appare per dichiarazioni del metodo di interfaccia , comunque.

8
Makoto

La nuova funzione Java 8 ( metodi predefiniti ) consente a un'interfaccia di fornire un'implementazione quando è etichettata con default parola chiave.

Ad esempio:

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

Test interfaccia utilizza la parola chiave predefinita che consente all'interfaccia di fornire un'implementazione predefinita del metodo senza la necessità di implementare tali metodi nelle classi che utilizzano l'interfaccia.

Compatibilità con le versioni precedenti: Immagina che la tua interfaccia sia implementata da centinaia di classi, la modifica di tale interfaccia costringerà tutti gli utenti a implementare il metodo appena aggiunto, anche se non essenziale per molte altre classi che implementano la tua interfaccia.

Fatti e restrizioni:

1-Può essere dichiarato solo all'interno di un'interfaccia e non all'interno di una classe o di una classe astratta.

2-Deve fornire un corpo

3-Non si presume che sia pubblico o astratto come altri metodi normali utilizzati in un'interfaccia.

2
Ahmad Sanie

Una buona spiegazione si trova in The Java ™ Tutorials , parte della spiegazione è la seguente:

Si consideri un esempio che coinvolge i produttori di auto controllate da computer che pubblicano interfacce standard del settore che descrivono quali metodi possono essere invocati per far funzionare le loro auto. Cosa succederebbe se quelle case automobilistiche controllate da computer aggiungessero nuove funzionalità, come il volo, alle loro auto? Questi produttori dovrebbero specificare nuovi metodi per consentire ad altre società (come i produttori di strumenti di guida elettronica) di adattare il proprio software alle auto volanti. In che modo queste case automobilistiche dichiarerebbero questi nuovi metodi relativi al volo? Se li aggiungono alle loro interfacce originali, i programmatori che hanno implementato tali interfacce dovrebbero riscrivere le loro implementazioni. Se li aggiungessero come metodi statici, i programmatori li considererebbero come metodi di utilità, non come metodi essenziali.

I metodi predefiniti consentono di aggiungere nuove funzionalità alle interfacce delle librerie e garantire la compatibilità binaria con il codice scritto per le versioni precedenti di tali interfacce.

2

I metodi predefiniti ti consentono di aggiungere nuove funzionalità alle interfacce delle tue app. Può anche essere usato per avere un multi ereditarietà. Oltre ai metodi predefiniti, è possibile definire metodi statici nelle interfacce. Ciò semplifica l'organizzazione dei metodi di supporto

1
user3359139

I metodi predefiniti in un'interfaccia ci consentono di aggiungere nuove funzionalità senza rompere il vecchio codice.

Prima di Java 8, se un nuovo metodo veniva aggiunto a un'interfaccia, tutte le classi di implementazione di quell'interfaccia dovevano sovrascrivere quel nuovo metodo, anche se non utilizzavano la nuova funzionalità.

Con Java 8, possiamo aggiungere l'implementazione predefinita per il nuovo metodo usando la parola chiave default prima dell'implementazione del metodo.

Anche con classi anonime o interfacce funzionali, se vediamo che un po 'di codice è riutilizzabile e non vogliamo definire la stessa logica ovunque nel codice, possiamo scrivere implementazioni predefinite di questi e riutilizzarli.

Esempio

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();
      }
   }
0
Dickson