Chaque nouvelle version de Java diffère de celles qui l'ont précédée. Voici un exemple de changements de matériel que nous avons couverts : avant Java 5, le langage n'avait pas
De même, Java 8 diffère sensiblement de Java 7. La plupart de nos leçons ont été écrites pour la 7ème version du langage, mais nous n'ignorerons bien sûr pas les innovations importantes. Puisque nous parlons déjà des interfaces dans cette leçon, nous allons considérer une mise à jour — les méthodes par défaut dans les interfaces . Vous savez déjà qu'une interface n'implémente pas behavior . Sa tâche est de décrire le comportement que tous les objets qui l'implémentent doivent avoir. Mais les développeurs ont fréquemment rencontré des situations où l'implémentation d'une méthode est la même dans toutes les classes. Prenons notre exemple de vieille voiture :
enum
de s. ![Méthodes par défaut dans les interfaces - 1](https://cdn.codegym.cc/images/article/34d25d0e-f8da-43f7-ab2b-5333c5a01585/800.jpeg)
public interface Car {
public void gas();
public void brake();
}
public class Sedan implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class Truck implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class F1Car implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
"A votre avis, quel est le principal problème avec ce code ? Vous avez probablement remarqué que nous avons écrit un tas de code répété ! Ce problème est courant en programmation et vous devez l'éviter. C'est une autre question que des solutions particulières n'existaient pas auparavant. Java 8 est sorti. Avec cette version est venue la possibilité de spécifier des méthodes par défaut et de les implémenter directement dans l'interface ! Voici comment procéder :
public interface Car {
public default void gas() {
System.out.println("Gas!");
}
public default void brake() {
System.out.println("Brake!");
}
}
public class Sedan implements Car {
}
public class Truck implements Car {
}
public class F1Car implements Car {
}
Désormais, les méthodes gas()
et brake()
, qui étaient les mêmes pour toutes les voitures, ont été déplacées vers l'interface. Aucun code répété n'est nécessaire. De plus, les méthodes sont disponibles dans chaque cours !
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();
}
}
Que se passe-t-il s'il y a 100 classes avec la gas()
méthode, mais que seulement 99 d'entre elles ont le même comportement ? Cela gâche-t-il tout et rend-il la méthode par défaut inadaptée à cette situation ? Bien sûr, non :) Les méthodes par défaut dans les interfaces peuvent être remplacées de la même manière que les méthodes ordinaires.
public class UnusualCar implements Car {
@Override
public void gas() {
System.out.println("This car accelerates differently!");
}
@Override
public void brake() {
System.out.println("This car decelerates differently!");
}
}
Tous les 99 autres types de voitures implémenteront la méthode par défaut, et leUnusualCar
la classe, qui est une exception, ne gâchera pas l'image globale et définira calmement son propre comportement. Héritage multiple des interfaces. Comme vous le savez déjà, Java ne prend pas en charge l'héritage multiple. Il y a plusieurs raisons à cela. Nous les examinerons en détail dans une leçon séparée. D'autres langages, tels que C++, le prennent en charge. Sans héritage multiple, un sérieux problème se pose : un objet peut avoir plusieurs caractéristiques et « comportements » différents. Voici un exemple tiré de la vie : nous sommes des enfants pour nos parents, des étudiants pour nos professeurs et des patients pour nos médecins. Dans la vie, nous assumons des rôles différents et, par conséquent, nous nous comportons différemment : évidemment, nous ne parlerions pas avec les enseignants de la même manière que nous parlons avec nos amis proches. Essayons de traduire cela en code. Imaginons que nous ayons deux classes : Étang et volière. Pour l'étang, nous avons besoin d'oiseaux aquatiques; pour la volière, nous avons besoin d'oiseaux volants. Pour ce faire, nous avons créé deux classes de base :FlyingBird
et Waterfowl
.
public class Waterfowl {
}
public class FlyingBird {
}
En conséquence, nous enverrons les oiseaux dont les classes héritent FlyingBird
de la volière, et nous enverrons les oiseaux qui héritent Waterfowl
de l'étang. Tout semble très simple. Mais où envoie-t-on un canard ? Il nage et vole. Et nous n'avons pas d'héritage multiple. Heureusement, Java prend en charge plusieurs implémentations d'interfaces. Bien qu'une classe ne puisse pas hériter de plusieurs parents, elle peut facilement implémenter plusieurs interfaces ! Notre canard peut être à la fois un oiseau volant et une sauvagine :) Nous avons simplement besoin de faire FlyingBird
et Waterfowl
d'interfaces plutôt que de classes pour arriver au résultat souhaité.
public class Duck implements FlyingBird, Waterfowl {
// The methods of both interfaces can be easily combined into one class
@Override
public void fly() {
System.out.println("Fly!");
}
@Override
public void swim() {
System.out.println("Swim!");
}
}
En conséquence, notre programme conserve la flexibilité des classes et, en combinaison avec les méthodes par défaut, notre capacité à définir le comportement des objets devient presque illimitée ! :)