Polymorphisme

Principe de l'OPP en Java

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

Pour simplifier, le polymorphisme permet au développeur d'utiliser une méthode ou un attribute selon plusieurs manières, en fonction du besoin. D'ailleurs, le mot polymorpsihm est apparu dans la Grèce antique. Il signifie quelque chose qui peut prendre plusieurs formes. Afin d'illustrer ce propos, regardons l'exemple d'une classe :

class Nationality {
    public String showNationality() {
        return "";
    }
}

class Polish extends Nationality {
    public String showNationality() {
        return "Polish citizen";
    }
}

class French extends Nationality {
    public String showNationality() {
        return "French citizen";
    }
}

Imaginons maintenant la situation où l'on veut implementer l'instance Nationality dans une des classes. Mais on ne sait pas si l'application va utiliser l'objet Polish ou French. C'est ici qu'on utilisera le polymorphisme :

class Citizen {
    public String fName = "First name";
    public String lName = "Last name";
  
    public Citizen(String fn, String ln) {
        this.fName = fn;
        this.lName = ln;
    }
  
    public String showCitizen(Nationality natInst) {
        return fName + " " + lName + "(" + natInst.showNationality() + ")";
    }

}

public class MainCitizen {
    public static void main(String[] args) {
        Polish pol = new Polish();
        Citizen cit = new Citizen("Bartosz", "Konieczny");
        System.out.println("Found citizen : " + cit.showCitizen(pol));
      }
}

Grâce à cet exemple on remarque bien que dans le polymorphisme, il faut toujours se référer à la classe-mère.

Il existent 3 implémentations différentes du polymorphisme :
- ad-hoc
Il s'agit de la surcharge. Il signifie la possibilité d'utiliser les mêmes éléments pour de différentes instances. On a pu le voir dans l'exemple évoqué ci-dessus. La méthode showNationality() surchargée retourne des Strings différents pour chaque nationalité.

Par exemple, en utilisant le caractère "+" sur des Strings, on va les concaténer. Par contre, en employant le même caractères sur des Integers, on va effectuer une addition.
- paramétrique
En Java, cette technique fait partie des generics qui permettent une meilleure clarté du code visant à limiter les erreurs. Regardons l'exemple issu du Wikipedia :

List<String> v = new ArrayList<String>();
v.add("test");
Integer i = v.get(0);

Au moment de compilation, on verra une erreur car on avait indiqué que la liste est composée de Strings. Il est donc impossible que son premier élément soit un Integer. Sans l'utilisation de generics, on aurait pu compiler le code. Cependant, au moment d'exécution on aurait reçu une runtime exception.

Le polymorphisme paramétrique est souvent couplé avec le polymorphisme ad-hoc. Revenons à notre exemple afin de l'illustrer :
interface Person {
    String showNationality();
    String sayHello();
}

class Citizen<P extends Person> {
    private P citizen;

    public Citizen(P citizen) {
        this.citizen = citizen;
    }
 
    public String sayHello() {
        return citizen.sayHello();
    }

    public String showNationality() {
        return citizen.showNationality();
    }
}

class Polish implements Person {
    public String showNationality() {
        return "Polish citizen";
    }
  
    public String sayHello() {
        return "Czesc";
    }
}

class French implements Person {
    public String showNationality() {
        return "French citizen";
    }
  
    public String sayHello() {
        return "Salut";
    }
}

public class Main {
    public static void main(String[] args) {
        Citizen<Polish> pol = new Citizen<Polish>(new Polish());
        System.out.println("Hello in Polish : " + pol.sayHello());

        Citizen<French> fre = new Citizen<French>(new French());
        System.out.println("Hello in French : " + fre.sayHello());
    }
}

- dynamic method binding
Cette technique permet de lier les instances des classes-filles à la classe-mère, sans créer l'instance de cette dernière. Regardons cela avec l'exemple de nos citoyens (on se réfère au premier exemple) :
public class Main {
    public static void main(String[] args) {
        Person cit;
        Polish pol = new Polish();
        French fre = new French();
    
        cit = pol;
        System.out.println("Citizen speaks in Polish : " + cit.sayHello());
    
        cit = fre;
        System.out.println("Citizen speaks also in French : " + cit.sayHello());
    }
}

Pour en savoir plus : http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html http://rpodhajny.wordpress.com/2009/02/27/java-polimorfizm/ http://home.cogeco.ca/~ve3ll/jatutor5.htm http://www.altcontroldelete.pl/artykuly/programowanie-obiektowe-polimorfizm/ http://prac.us.edu.pl/~dendzik/java/i3/index.html http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29 http://en.wikipedia.org/wiki/Generics_in_Java http://stackoverflow.com/questions/10179449/what-is-parametric-polymorphism-in-java-with-example Traitement d'une instance en fonction de besoin : s'il hérite d'une interface et d'une classe-mère, on peut le traiter soit comme l'objet de l'interface ou de la classe-mère. Un bon exemple est la situation où on a une classe qui doit hériter d'une autre, tout en possédant une nouvelle méthode (qui quant à elle ne doit pas se trouver dans la classe-mère).

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 PHP

Problème lors d'implode du saut de ligne ?

Si tu tentes d'introduire un saut de ligne (\r\n) dans un fichier, fais attention. L'appel implode(' \r\n ', $array) ne l'ajoutera pas car '\r\n' est traité comme une chaîne de caractères.

Pour réussir la manipulation, il faut appeler implode(" \r\n ", $array).