JavaRush /Java Blog /Random-IT /Metodi predefiniti nelle interfacce

Metodi predefiniti nelle interfacce

Pubblicato nel gruppo Random-IT
Ogni nuova versione di Java è diversa dalle precedenti. Ecco un esempio delle modifiche rispetto al materiale trattato: Prima di Java 5, non c'erano enumle " nel linguaggio ".
Metodi predefiniti nelle interfacce - 1
Allo stesso modo, Java 8 è notevolmente diverso da Java 7. La maggior parte delle nostre lezioni sono scritte nella settima versione del linguaggio, ma, ovviamente, non ignoreremo importanti innovazioni. Dato che in questa lezione parleremo di interfacce, diamo un'occhiata a un aggiornamento: i metodi predefiniti in interfacce . Sai già che un'interfaccia non implementa . Il suo compito è descrivere quale comportamento dovrebbero avere tutti gli oggetti che lo implementano . Ma molto spesso gli sviluppatori si sono imbattuti in situazioni in cui l'implementazione di un metodo in tutte le classi era la stessa. Diamo un'occhiata al nostro esempio di vecchia macchina:
public interface Car {

   public void gas();

   public void brake();
}
public class Sedan implements Car {

   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}


public class Truck implements Car {

   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}


public class F1Car implements Car {
   @Override
   public void gas() {
       System.out.println("Газ!");
   }

   @Override
   public void brake() {
       System.out.println("Тормоз!");
   }
}
Quale pensi sia il problema principale di questo codice? Probabilmente hai notato che abbiamo scritto un sacco dello stesso codice! Questo problema è comune nella programmazione e dovrebbe essere evitato. Un'altra cosa è che prima del rilascio di Java 8 non esistevano opzioni di soluzione speciali. Quando è uscita questa versione, è diventato possibile definire metodi predefiniti e implementarli direttamente all'interno dell'interfaccia! Ecco come è fatto:
public interface Car {

   public default void gas() {
       System.out.println("Газ!");
   }

   public default void brake() {
       System.out.println("Тормоз!");
   }
}

public class Sedan implements Car {

}

public class Truck implements Car {

}

public class F1Car implements Car {

}
Ora i metodi gas()e brake(), che erano gli stessi per tutte le macchine, sono inclusi nell'interfaccia e non è più necessario il codice duplicato. Inoltre, i metodi sono disponibili in ciascuna delle classi!
public class Main {

   public static void main(String[] args) {

       F1Car f1Car = new F1Car();
       Sedan sedan = new Sedan();
       Truck truck = new Truck();
       truck.gas();
       sedan.gas();
       f1Car.brake();
   }
}
Cosa succede se ci sono 100 classi con un metodo gas(), ma solo 99 di esse hanno lo stesso comportamento? Questo rovina tutto e il metodo predefinito non funzionerà in questo caso? Ovviamente no :) I metodi predefiniti delle interfacce possono essere sovrascritti.
public class UnusualCar implements Car {
   @Override
   public void gas() {
       System.out.println("Эта машина газует по-другому!");
   }

   @Override
   public void brake() {
       System.out.println("Эта машина тормозит по-другому!");
   }
}
Tutti gli altri 99 tipi di macchine implementeranno il metodo predefinito e la classe UnusualCar, l'eccezione, non rovinerà il quadro generale e ne determinerà con calma il comportamento. Ereditarietà multipla nelle interfacce Come già sapete, in Java non esiste l'ereditarietà multipla. Le ragioni sono molte e le vedremo in dettaglio in una lezione a parte. In altri linguaggi, ad esempio in C++, è il contrario. Senza l'ereditarietà multipla sorge un problema serio: lo stesso oggetto può avere numerose caratteristiche e "comportamenti" diversi. Un esempio dalla vita: per i nostri genitori siamo figli, per gli insegnanti siamo studenti, per i medici siamo pazienti. Nella vita appariamo in ruoli diversi e, di conseguenza, ci comportiamo in modo diverso: ovviamente parleremo con gli insegnanti in modo diverso rispetto agli amici intimi. Proviamo a tradurre questa situazione in codice. Immaginiamo di avere due classi: Pond e Aviary. Per uno stagno hai bisogno di uccelli che nuotano e per una voliera hai bisogno di uccelli che volano. Per fare ciò, abbiamo creato due classi base: FlyingBirde Waterfowl.
public class Waterfowl {
}

public class FlyingBird {
}
Di conseguenza, invieremo alla voliera quegli uccelli le cui classi sono ereditate da FlyingBird, e allo stagno - quelli che discendono da Waterfowl. Tutto sembra semplice. Ma cosa faremo se dovessimo identificare l'anatra da qualche parte? Nuota e vola allo stesso tempo. Ma non abbiamo l'ereditarietà multipla. Fortunatamente, Java fornisce molteplici implementazioni di interfacce. Se una classe non può ereditare da più genitori, implementare diverse interfacce è facile! La nostra anatra può sia volare che nuotare :) È sufficiente utilizzare le interfacce FlyingBirdanziché Waterfowlle classi per ottenere il risultato desiderato.
public class Duck implements FlyingBird, Waterfowl {

   //методы обоих интерфейсов легко объединяются в одном классе

   @Override
   public void fly() {
       System.out.println("Летим!");
   }

   @Override
   public void swim() {

       System.out.println("Плывем!");
   }
}
Grazie a ciò, il nostro programma mantiene una gestione flessibile delle classi e, in combinazione con l'implementazione di metodi predefiniti, la nostra capacità di definire il comportamento degli oggetti diventa quasi illimitata! :)
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION