ICS4U

Accueil > Classes et objets >

📚 Les objets

Survol et attentes

Si vos projets Java jusqu’à présent tenaient dans une seule classe, ces projets n’utilisaient pas le plein potentiel, ni même l’objectif, du langage Java. Ce langage a été développé quand l’Internet est devenu accessible au public pour créer des projets orientés-objet plus sécures et plus facilement distribuable que ce qui existaient déjà.

Mais pour des projets orienté-objet, il faut définir des objets, ce que vous n’avez pas fait intentionnellement jusqu’à présent.

Définitions
Objet
Une abstraction - un modèle informatique - pour quelque chose qui existe dans le monde réel (ou dans notre imagination). Un objet est défini dans une classe qui contient des attributs et des méthodes. On crée des instances de l’objet en déclarant des variables du type de l’objet. Par exemple, Scanner input = new Scanner(System.in); crée une instance de Scanner nommée input.
Encapsulation
Le regroupement des données et des méthodes qui les manipulent dans une seule entité.1 Les classes Java sont un exemple d’encapsulation, notamment les classes qui définissent des objets.
Classe objet
Une classe définissant un modèle pour un objet en déclarant des attributs pour ses informations et des méthodes pour ses comportements. Ces classes encapsulent dans une seule entité les données avec les méthodes qui les manipulent afin de créer un modèle adéquatement complet de l’objet.2
Instance
Un objet en mémoire avec sa propre copie de chaque attribut de la classe objet et qui peut utiliser toutes les méthodes de la classe.
Classe pilote
Une classe qui contient la méthode main pour la logique globale du programme. C’est la classe qui est lancée pour exécuter le programme. Elle crée et utilise des instances d’autres classes objets.
Mot-clé new
Utilisé pour créer une instance d’un objet correspondant au modèle défini dans une classe. Par exemple, new Scanner(System.in) crée une instance de la classe Scanner qui lit l’entrée standard.
Mot-clé this
Utilisé dans les méthodes d’une classe objet pour faire référence à l’instance spécifique qui a fait l’appel de la méthode. C’est utile pour différencier les attributs de l’instance de variables locales dans la méthode comme les paramètres.
Attribut
Une variable définie à la racine d’une classe objet.
Méthode
Une fonction définie dans une classe objet. Ces fonctions opèrent directement sur les attributs de la classe.
Commande javac
Commande nécessaire pour compiler un projet Java comportant plus qu’un fichier .java. Si tous les fichiers sont dans le dossier racine directement, la commande javac *.java compile tous les fichiers .java dans le dossier, générant les fichiers .class correspondants. On lance ensuite le programme avec java NomDeLaClassePilote (sans l’extension .class ou .java).

Objectifs d’apprentissage

À la fin de cette leçon vous devrez être en mesure de :

Critères de succès

Structure de projet orienté-objet Java

Un projet orienté objet tient dans plusieurs classes - typiquement une classe par fichier, notamment :

  • Une classe qui contient la méthode main pour la logique globale du programme -> on l’appelle la classe pilote. Voici quelques exemples de noms pour la classe pilote :
    • Driver.java
    • Main.java
    • App.java
  • Une ou plusieurs classes qui définissent des objets. On crée des instances de ces objets dans le pilote ou dans d’autres objets.
  • Classes pour les tests unitaires afin de valider le comportement des méthodes dans les classes objets un par un.

Les outils Java standard créent des structures de projets avec des dossiers pour les sources, les tests et les ressources. Les fichiers sources (comme le pilote et les objets) sont dans le dossier src et les fichiers tests dans le dossier test.

Pour le moment, nous créerons des projets simples sans structure spécifique : tous les fichiers .java seront dans le même dossier. La structure des fichiers pour un projet simple pourrait ressembler à ceci :

1
2
3
4
.
├── App.java
├── Person.java
└── TestPerson.java

Pour compiler ce projet, on ouvre le terminal dans le dossier racine du projet et on tape :

1
javac *.java

Ce qui ajoute les fichiers .class au dossier s’il n’y a pas d’erreurs de compilation. En cas d’erreurs de compilation, les messages d’erreur seront affichés à la console. Il faut faire cette étape de compilation à chaque modification du projet, sinon les fichiers .class utilisés pour lancer le programme ne seront pas à jour.

Finalement, pour lancer le programme, on tape :

1
java App

On ignore le fichier TestPerson.java ici parce que ce fichier est souvent généré et utilisé par des outils de test comme JUnit accessibles dans votre EDI. Pour plus d’information sur les tests unitaires, voir les notes du cours ICS3U

Les objets

Un objet est une abstraction - un modèle informatique - pour quelque chose qui existe dans le monde réelle (ou dans notre imagination). Le modèle pour un objet est défini dans une classe qui contient des :

  • informations -> ce qu’on appelle les attributs de l’objet. Ce sont des variables définies à la racine de la classe.
  • comportements -> ce qu’on appelle les méthodes de l’objet.

Voici quelques exemples d’objets qu’on utilise déjà :

  • String : un modèle pour un texte
  • Scanner : un modèle pour un lecteur de texte
  • File : un modèle pour un élément du système de fichiers.

Ces objets sont définies dans une classe du même nom dans les fichiers String.java, Scanner.java et File.java à divers endroits dans la trousse de développement de Java (JDK).

Définir un objet

Pour définir un objet, il suffit de créer une nouvelle classe dans un fichier .java du même nom, de déclarer ses attributs et de définir des méthodes.

Par exemple, dans Person.java :

1
2
3
4
5
6
7
8
9
10
class Person {
    // attributs
    String name;
    int age;

    // méthode
    void speak() {
        System.out.println(name + "dit 'Allô!'");
    }
}

Notez qu’il n’y a pas de méthode main dans cette classe, seulement les informations qui représentent notre modèle simple d’une personne (name et age) et d’un comportement associé (speak).

Utiliser un objet, partie 1 - créer des instances

Pour utiliser un objet, on déclare une variable du type de l’objet dans une méthode ou une classe. Chaque objet ainsi nommé s’appelle une instance de l’objet.

Exemple 1 : input est une instance de Scanner

1
2
3
4
5
6
7
import java.util.Scanner;

class App {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
    }
}

Exemple 2 : jenny et andrew sont des instances de Person

1
2
3
4
5
6
class Main {
    public static void main(String[] args) {
        Person jenny = new Person();
        Person andrew = new Person();
    }
}
  • Chaque instance a son propre bloc en mémoire pour sa propre copie des attributs. Par exemple, l’instance jenny a son propre bloc en mémoire pour name et age. De même, l’instance andrew a son propre bloc en mémoire pour name et age.
  • Chaque instance peut utiliser toutes les méthodes de la classe.

Utiliser un objet, partie 2 - utiliser les attributs et les méthodes

Pour utiliser les attributs et les méthodes d’une instance, on utilise l’opérateur . après le nom de l’instance suivi par le nom de l’attribut ou de la méthode.

1
2
3
4
5
6
7
8
9
10
11
12
class Main {
    public static void main(String[] args) {
        Person jenny = new Person();
        // Modifier les attributs
        jenny.name = "Jenny";
        jenny.age = 16;
        // Utiliser les méthodes
        jenny.speak();
        // Afficher les attributs
        System.out.println(jenny.name + " a " + jenny.age + " ans.");
    }
}

Tentez de noter chaque fois que vous avez vu l’opérateur . dans les programmes que vous avez produits en ICS3U et en ICS4U jusqu’à présent (comme System.out.println()). Chaque fois, c’était pour accéder à un attribut ou une méthode d’un objet.

Par exemple, System.out.println() : out est un attribut de type PrintStream dans la classe System, et println() est une méthode de la classe PrintStream accessible par l’instance out.

Mot-clé this

Reprenons l’exemple de l’objet Person définit plus haut et ajoutons les méthodes changeName() et happyBirthday().

Person.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person {
    String name;
    int age;

    void speak() {
        System.out.println(name + "dit 'Allô!'");
    }

    void changeName(String name) {
        this.name = name;
    }

    void happyBirthday(){
        age += 1;
    }
}

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Main {
    public static void main(String[] args) {
        Person jenny = new Person();
        jenny.name = "Jenny";
        jenny.age = 16;

        Person andrew = new Person();
        andrew.name = "Andrew";
        andrew.age = 17;

        andrew.happyBirthday();
        // andrew.age est maintenant 18

        jenny.changeName("Jen");
        // jenny.name est maintenant "Jen"
    }
}

Le mot-clé this dans les méthodes de la classe objet est utilisé pour faire référence à l’instance spécifique qui fait appel à la méthode.

Dans l’exemple ci-dessus, on le voit à un seul endroit, dans la méthode changeName(). On utilise this.name pour différencier la variable de l’instance name de la variable locale name passée en paramètre. Si vous copiez cette exemple dans votre IDE, en cliquant sur chaque name dans la méthode changeName(), vous verrez que celui précédé par this. surligne également la déclaration de l’attribut name de la classe tandis que l’autre surligne la déclaration du paramètre name. Si vous enlevez le this., le compilateur ne saura pas quelle variable name vous voulez modifier et vous donnera une erreur (surlignée en rouge).

Notez que dans les méthodes speak() et happyBirthday(), on n’a pas besoin de this. parce qu’il n’y a pas de confusion possible. En l’absence de variables locales, les références à name et age peuvent seulement être celles de l’instance. Dans de tels cas, vous pouvez tout de même utiliser this. pour plus de clarté, mais ce n’est pas nécessaire.

Exercices

📚 Tester la compréhension

Quiz de vérification sur les objets

🛠️ Pratique

Produire une classe pilote et une classe qui définit un objet. Pour l’objet, modélisez quelque chose de votre vie qui existe en plusieurs instances. p. ex.: films, jeux, vélos, véhicules, artistes/athlètes/politiciens préférés, etc. Créer une ou deux instances de votre objet dans la méthode main() du pilote, assigner des valeurs à chaque attribut et tester les différentes méthodes. Afficher les valeurs au besoin avec des System.out.println().

  1. Plusieurs définitions de l’encapsulation incluent aussi l’idée de cacher les détails d’implémentation pour protéger les données, généralement en rendant les attributs privés et en fournissant une interface publique de méthodes pour les manipuler. Voir la leçon sur le masquage de l’information pour plus de détails. 

  2. Dans les langages multi-paradigmes (comme Python) ou fonctionnelles (comme JavaScript, Rust), il y a d’autres façons d’encapsuler des données et des comportements à part les classes, notamment les fermetures / clôtures (closures en anglais). Par contre, la programmation orientée-objet utilise presque toujours les classes pour l’encapsulation.