Implements et extends

Implémenter ou hériter des interfaces ou des classes

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

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-e

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

Une question ? Une remarque ?

*

*

Moi

Développeur d'applications Internet et journaliste passionné par l'adjectif français. Un aigle polonais orienté vers la progression, volant très haut et écoutant du zouk après les matches du foot français.

Vous appréciez mon travail ?

Pour contribuer au développement de ce site, ou pour remercier pour des articles rédigés, vous pouvez faire un don.

Un conseil Symfony1

Comment détecter si l'utilisateur est connecté ?

Dans notre fichier layout.php on contient une partie réservée aux utilisateurs connectés et non-connectés. Pour pouvoir détecter cela sans trop de complication, on devrait utiliser les slots. Le fichier d'action va contenir le framgent suivant en fonction du type de l'utilisateur (connecté ou pas) :

$this->getResponse()->setSlot('isConnected', 'true');
Alors dans le fichier layout.php on pourra utiliser ceci :
if(!has_slot('isConnected')  ) {
  // include login form
  include_partial('users/formLogin');
}
else {
  include_partial('users/accountBox');
}