Précédent Suivant

Instances et classes en Java : les Objets


Les classes et les instances
Les constructeurs
Les membres statiques
La classe principale : Object
Exercices

En java, hormis les primitives citées précedemment, on peut dire que tout est objet. Le principe fondamental d'un langage objet est de pouvoir modéliser et solutionner un problème à l'aide des éléments constituant le problème. Si notre problème concerne le traitement d'une image, il sera beaucoup plus facile conceptuellement de manipuler un objet image plutôt qu'une suite de 0 et de 1.
Cette approche est considérée comme la plus naturelle car elle correspond un peu à notre façon d'appréhender les choses. La modélisation d'un problème, même si elle est très déroutante par rapport à une approche déclarative come on pouvait le faire en Pascal, en est donc très facilitée.
En java on parlera exclusivement de classes et d'instances de classes. Les instances de classes peuvent être assimilées à des objets.

Les classes et les instances
Les classes permettent en quelque sorte de décrire une catégorie d'objets. L'ensemble des objets de cette catégorie seront les instances de ces classes. Un exemple classique et formateur est de travailler sur une classe qui représente un animal.
Supposons que l'on dispose d'une classe animal. Un animal a toujours un nom et une couleur par exemple. Voici comment on pourrait le modéliser en utilisant le langage de notation unifié UML :

Une implémentation en Java pourrait être :

public class Animal {
    String nom, couleur;
    public getNom() {
        return nom;
    }
    public setNom(String nom) {
        this.nom = nom;
    }
    public getCouleur() {
        return couleur;
    }
    public setCouleur(String couleur) {
        this.couleur = couleur;
    }
}

public class CreateAnimal {
    public static void main(String argv[]) {
        Animal a = new Animal();
        a.setNom("Médor");
        a.setCouleur("Noir");
        System.out.println(a.getNom()+" est de couleur "+a.getCouleur());
    }
}

On s'aperçoit que l'instanciation d'une classe passe par l'utilisation du mot réservé new. On peut ensuite invoquer les méthodes setNom et setCouleur pour donner un nom et une couleur à notre chien.
Maintenant, reprenons le modèle ci-dessus. Médor et Félix sont tous les deux des animaux, mais Médor semble plutôt être un chien et Félix un chat. On peut alors affiner le modèle comme suit :

On déclare deux classes supplémentaires, Chien et Chat, qui héritent de Animal. Un Chien est un Animal et un chat est un Animal. Ces deux classes reprennent les mêmes propriétés que la classe Animal : c'est la notion d'héritage. La classe Animal devient ainsi abstraite, c'est à dire qu'elle n'est plus instanciée directement. On peut spécifier ces classes en disant qu'un chien aboie et qu'un chat miaule. La notion d'héritage s'implémente en Java avec le mot clé extends :

public class Chien extends Animal {
    public String aboie() {
        return "OUAF OUAF";
    }
}

public class CreateAnimal {
    public static void main(String argv[]) {
        Chien monChien = new Chien();
        monChien.setNom("Médor");
        monChien.setCouleur("Noir");
        System.out.println("Mon chien s'appelle "+monChien.getNom()+" et il fait "+monChien.aboie());
     }
}

Les constructeurs
Les constructeurs permettent d'effectuer un certain traitement au moment de l'instanciation de l'objet lui même. Un constructeur est une méthode qui a la particularité de posséder le même nom que la classe à laquelle il appartient. Pour reprendre notre exemple, pour éviter d'invoquer les méthodes setNom() et setCouleur() juste après l'instanciation, on pourrait mettre ce traitement dans le constructeur de cette façon :

public class Chien extends Animal {
    public Chien(String nom, String couleur) {
        setNom(nom);
        setCouleur(couleur);
    }

    public String aboie() {
        return "OUAF OUAF";
    }
}

Et instancier le Chien comme suit :

Chien monChien = new Chien("Médor", "Noir");

Cependant, si on veut que tous les animaux bénéficient de ce constructeur bien pratique, il aurait fallu le mettre directement dans la classe Animal. Dans ce cas, il faut aussi créer un constructeur dans la classe Chien qui invoque le constructeur de sa surclasse. Le mot clé super sert à ça :

public class Animal {
    String nom, couleur;
    public Animal(String nom, String couleur) {
        this.nom = nom;
        this.couleur = couleur;
    }

    public getNom() {
        return nom;
    ...

public class Chien extends Animal {
    public Chien(String nom, String couleur) {
        super(nom, couleur);
    }
    public String aboie() {
        return "OUAF OUAF";
    }
}

Les membres statiques
Chaque Chien possède un nom différent, il est donc normal que chaque instance de Chien possède la propriété nom. Cependant tout le monde est unanime pour dire que tous les chiens ont quatre pattes. Il serait donc peu judicieux que chaque instance de Chien possède la même propriété. Pour remédier à cela, Java propose les variables de classes ou encore variables statiques, qui permettent de partager (en lecture et écriture) certaines valeurs entre instances d'une même classe. Le mot réservé est static. Par exemple :

public class Chien extends Animal {
    static int nombrePattes = 4;
    public Chien(...

La classe principale : la classe Object
Pour conclure sur les objets en Java, on peut dire que toutes les classes quelles qu'elles soient, prédéfinies ou créées par l'utilisateur, héritent tous de la classe Object, la classe principale de Java. Et quand on déclare une classe sans la faire hériter explicitement de Object, le compilateur se charge de le rajouter. Une classe hérite toujours implicitement de Object. Les deux déclarations suivantes sont donc équivalentes :

public class Animal {
public class Animal extends Object {

Exercices
1 - Implémentez une classe Lineaire qui calcule les éléments d'une fonction linéaire puis une classe Affine qui calcule les éléments d'une fonction affine. Ces deux classes doivent posséder une méthode getNextElement(), qui à chaque fois qu'on l'invoque, retourne l'élément suivant de la liste. Utilisez la notion d'héritage pour représenter le fait qu'une fonction affine est une fonction linéaire à laquelle on rajoute un paramètre. Faites un programme qui affiche les 10 premiers éléments de chaque fonction.
Linéaire : y = ax
Affine : y = ax+b
2 - Implémentez une classe Fibonacci qui calcule les éléments d'une suite de Fibonacci.


Précédent Suivant