Sémantiquement, on devrait utiliser le mot extends si notre classe hérite d'une autre. Quand à implements, il devrait être employé dans le cas d'implémentation d'une interface. Cependant en Java ce n'est pas toujours le cas.
L'exception à cette règle concerne les generics. Dans le cas de l'implémentation d'une interface dans generics, le choix d'opération est limité à deux possibilités : extends et super.
Extends se réfère soit à des classes-mères, soit à la classe implémentant ou héritant des classes-mères. Donc on va accepter soit la classe-mère, soit toutes ses filles.
VOIR L'EXEMPLE D'EXTENDS http://stackoverflow.com/questions/1368166/what-is-a-difference-between-super-e-and-extends-eSuper se positionne par rapport à l'arborescence d'une classe à l'autre. Autrement dit, on accepte soit la classe elle-même (une et une seule), soit une de ses classes-mères.
La différence entre les deux devrait être très facile à saisir grâce à cette exemple :
import java.util.List; import java.util.ArrayList; public class ImplementsOrExtends { public static void main(String[] args) { // Class hierarchy for Integer : // -- Object // | // | // -------- Number // | // | // ---------------- Integer // ---------------- Double List<? super Integer> superIntegerNumber eee= new ArrayList<Number>(); List<? super Integer> superIntegerInteger = new ArrayList<Integer>(); List<? super Integer> superIntegerDouble eee= new ArrayList<Double>(); List<? extends Number> extendsNumberNumber = new ArrayList<Number>(); List<? extends Number> extendsNumberInteger = new ArrayList<Integer>(); List<? extends Number> extendsNumberDouble eee= new ArrayList<Double>(); List<? extends Number> extendsNumberObject eee= new ArrayList<Object>(); } }
En essayant de compiler le fichier, on reçoit deux erreurs :
ImplementsOrExtends.java:19: incompatible types found eee: java.util.ArrayList<java.lang.Double> required: java.util.List<? super java.lang.Integer> List<? super Integer> superIntegerDouble eee= new ArrayList<Double>();
La compilation est impossible car Double se trouve au même niveau qu'Integer. Il ne peut pas donc être sa classe-mère.
ImplementsOrExtends.java:24: incompatible types found eee: java.util.ArrayList<java.lang.Object> required: java.util.List<? extends java.lang.Number> List<? extends Number> extendsNumberObject eee= new ArrayList<Object>();
La compilation est impossible car Object n'hérite pas de Number (il est sa classe-mère).
Pour corriger le code, il faut enlever les deux lignes qui nous ont servis à bien comprendre la nuance entre extends et super. Voici le code corrigé :
import java.util.List; import java.util.ArrayList; public class ImplementsOrExtends { public static void main(String[] args) { // Class hierarchy for Integer : // -- Object // | // | // -------- Number // | // | // ---------------- Integer // ---------------- Double List<? super Integer> superIntegerNumber eee= new ArrayList<Number>(); List<? super Integer> superIntegerInteger = new ArrayList<Integer>(); // List<? super Integer> superIntegerDouble eee= new ArrayList<Double>(); List<? extends Number> extendsNumberNumber = new ArrayList<Number>(); List<? extends Number> extendsNumberInteger = new ArrayList<Integer>(); List<? extends Number> extendsNumberDouble eee= new ArrayList<Double>(); // List<? extends Number> extendsNumberObject eee= new ArrayList<Object>(); } }