Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Apprendre à coder une classe générique

Introduction à la généricité en Java Définition de méthodes génériques



Accès rapide :
La vidéo
Implémentation d'une classe générique
Utilisation de notre classe générique
Restriction du typage sur une classe générique

La vidéo

Cette vidéo vous montre comment coder une classe générique en Java ainsi que comment l'utiliser. La restriction des types utilisables par votre classe générique, vous est aussi présentée.


Apprendre à coder une classe générique

Implémentation d'une classe générique

Nous allons maintenant apprendre à coder une classe générique. Pour indiquer qu'un type est générique, il faut ajouter la liste des types génériques supportés entre caractères < et > à la suite du nom de la classe et avant l'accolade ouvrante.

 1 
 2 
 3 
 4 
 5 
public class GenericBox<ELEMENT> {

    // TODO: implémentation de la classe générique

}
On définit la liste des types de généricité
dans notre exemple, nous avons défini qu'un seul type générique et nous l'avons appelé ELEMENT. Java préconise des conventions de codage : il y est dit qu'un nom de type générique doit être une seule lettre en majuscule pour le différentier d'un nom de type classique. Personnellement, je préfère mettre un nom complet indiquant bien ce qu'il représente. Dans le cas considéré, ce type de généricité se nomme ELEMENT.

Il est possible de définir une classe générique avec plusieurs types de généricité. Par exemple, nous avons parlé dans le chapitre précédent du type java.util.Map qui manipule des clé et des valeurs Pour définir une telle classe, séparez vos types de généricité avec des virgules. Voici un exemple de syntaxe.

 1 
 2 
 3 
 4 
 5 
public class MyMap<KEY, VALUE> {

    // TODO: implémentation de la classe générique

}
On définit la liste des types de généricité

Reprenons l'exemple de notre classe GenericBox à un type de généricité. Il faut maintenant définir les attributs et les méthodes qui vont constituer cette classe. Ces membres vont certainement devoir utiliser le type de généricité : utilisez simplement le nom ELEMENT pour y faire référence. Voici le contenu de notre classe générique.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
public class GenericBox<ELEMENT> {
    
    private ELEMENT element;
    
    
    public GenericBox( ELEMENT element ) {
        this.setElement( element );
    }   
    
    
    public ELEMENT getElement() {
        return element;
    }
    
    public void setElement( ELEMENT element ) {
        if ( element == null ) throw new NullPointerException( "null is not permit" );
        this.element = element;
    }

    // Other methods
    
}
Implémentation d'une classe générique

Utilisation de notre classe générique

Nous allons maintenant utiliser notre type générique. Nous allons créer une instance de la classe GenericBox en la spécialisant sur le type String. Le constructeur et les méthodes getElement et setElement manipuleront donc des chaînes de caractères.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
public class Start {
    
    public static void main(String[] args) {
        
        GenericBox<String> box = new GenericBox<>( "toto" );
        System.out.println( box.getElement() );
        box.setElement( "tata" );
        System.out.println( box.getElement() );

    }

}
Utilisation de notre classe générique

Restriction du typage sur une classe générique

Il est possible de limiter les types utilisables pour une classe générique. Par exemple, si l'on souhaite que notre classe GenericBox soit limitée à des types dérivant d'une classe Person (imaginez plusieurs classes qui dérivent de cette classe Person), utilisez la syntaxe suivante.

 1 
 2 
 3 
 4 
 5 
public class GenericBox<ELEMENT extends Person> {

    // TODO: implémentation de la classe générique

}
Limitation des types utilisables

Voici un exemple plus complet qui permet d'envelopper n'importe quel composant Swing dans une fenêtre. Les types utilisables sont donc limités à n'importe quel composant graphique (dérivant de java.awt.Component).

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
import java.awt.BorderLayout;
import java.awt.Component;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;

@SuppressWarnings( {"serial", "unused"} )
public class GenericContainer<COMPONENT extends Component> extends JFrame {

    private COMPONENT myComponent;
    
    public GenericContainer( COMPONENT component ) {
        super( "Generic Container" );
        this.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );

        JPanel contentPane = (JPanel) getContentPane();
        contentPane.add( component, BorderLayout.CENTER );
        
        this.pack();
        this.setLocationRelativeTo( null );
        
        this.setVisible( true );
    }

    public COMPONENT getMyComponent() {
        return myComponent;
    }
    
    // Le point d'entrée de notre programme
    public static void main(String[] args) {
        
        // Deux exemples d'utilisation de notre classe générique
        // sur un bouton et un composant de type JTree
        GenericContainer<JButton> frame = new GenericContainer<>( new JButton("Click me!") );
        JButton btn = frame.getMyComponent();
        
        GenericContainer<JTree> frame2 = new GenericContainer<>( new JTree() );
        JTree tree = frame2.getMyComponent();
        
        // Par contre, cette ligne de code ne compile pas, car une chaîne  
        // de caractères n'est pas un composant graphique.
        //GenericContainer<String> frame = new GenericContainer<>( "toto" );
        
    }
}
Limitation des types utilisables
Si vous ne connaissez pas encore la librairie d'interface graphique Swing, sachez qu'un cours / tutoriel est disponible en activant ce lien.


Introduction à la généricité en Java Définition de méthodes génériques