Classes et objets en Java
toString lisible, puis termine en concevant, construisant et testant une classe complète à partir d’une courte description.DébutantUnité 5 sur 11 de la formation Formation : Java orienté objet : classes, collections, héritage et tests
Ce que tu vas apprendre
- Explique comment une classe définit un nouveau type de données doté de son propre comportement, puis crée et utilise des objets de ce type dans un programme.
- Explique ce que sont une classe et un objetDécris une classe comme la définition d’un type, un objet comme une instance de ce type, et l’état et le comportement comme ce que les objets contiennent et font.
- Crée des objets et appelle leurs méthodesCrée des objets avec
new, appelle leurs méthodes avec la notation pointée et prévois le comportement d’objets distincts.
- Explique ce que sont une classe et un objet
- Déclare les variables d’instance qui contiennent l’état d’un objet et écris des constructeurs qui donnent à chaque nouvel objet des valeurs initiales valides.
- Déclare des variables d’instanceDéclare des champs de types adaptés, connais leurs valeurs par défaut et distingue-les des variables locales et des paramètres.
- Écris des constructeurs qui initialisent les objetsÉcris des constructeurs qui définissent chaque champ, utilise
thispour distinguer les champs des paramètres et évite les erreurs qui laissent des champs sans valeur définie. - Propose plusieurs constructeurs et chaîne-lesSurcharge les constructeurs pour proposer différentes façons de créer un objet et utilise
this(...)afin de n’écrire le code d’initialisation qu’une fois.
- Déclare des variables d’instance
- Écris des méthodes d’instance qui lisent et modifient l’état d’un objet, suis leurs effets et décide quand un élément appartient à un objet ou à la classe entière.
- Écris des méthodes d’instance qui utilisent et modifient l’étatÉcris des méthodes qui donnent des informations sur les champs d’un objet ou les modifient, appelle d’autres méthodes du même objet et suis l’état des objets étape par étape.
- Distingue les membres d’instance des membres statiquesUtilise
thispour désigner l’objet courant, décide de ce qui doit être statique et corrige les erreurs dues au mélange de code statique et de code d’instance.
- Écris des méthodes d’instance qui utilisent et modifient l’état
- Masque les champs à l’aide de modificateurs d’accès, donne un accès contrôlé par des accesseurs, des mutateurs et des méthodes adaptées, et conserve chaque objet dans un état valide.
- Masque les données avec des modificateurs d’accèsUtilise
private, l’accès de paquetage,protectedetpublicpour contrôler le code qui peut utiliser les membres d’une classe, et explique pourquoi les champs sont privés. - Écris des accesseurs et des mutateursÉcris des méthodes d’accès et de modification avec les noms standard, puis décide quels champs en ont besoin et quand une méthode qui décrit une action est préférable.
- Préserve la validité des objets à l’aide de vérificationsDéfinis les règles que l’état d’un objet doit respecter, fais-les appliquer par les constructeurs et les méthodes et évite de fournir des données internes qui permettent de contourner ces vérifications.
- Masque les données avec des modificateurs d’accès
- Donne aux objets une forme textuelle lisible avec
toString, puis conçois, écris et teste une classe complète à partir d’une courte description.- Écris une méthode toStringÉcris une méthode
toStringqui renvoie une description lisible d’un objet et identifie quand Java l’appelle automatiquement. - Conçois, construis et teste une classe complèteTransforme une courte description en une classe avec des champs, des constructeurs, des méthodes et des règles, puis teste chaque comportement depuis un programme principal.
- Écris une méthode toString
Classes et objets en Java : cours
1Classes, objets et appels de méthodes
Un programme doit souvent conserver ensemble plusieurs valeurs liées : le nom, l’espèce et l’âge d’un animal de compagnie, par exemple. Une classe donne un type à ce groupe et rassemble les actions qui l’utilisent. Tu associeras les définitions de classes aux objets créés pendant l’exécution d’un programme, puis tu suivras les appels de méthodes pour voir les données de quel objet changent. La distinction entre une classe, un objet et une variable t’aidera à lire le code que tu écriras ensuite.
1.1 Un type avec un état et un comportement
Une classe définit un type : les données que ses objets mémorisent et les opérations qu’ils proposent. Un objet, aussi appelé instance, est une valeur de ce type créée pendant l’exécution d’un programme. Écrire une définition de classe ne crée pas d’objet.
État et comportement
Le nom, l’espèce et l’âge d’un animal de compagnie constituent son état. Ces valeurs actuelles sont contenues dans des variables d’instance, aussi appelées champs. Une opération comme fêter un anniversaire est un comportement, écrit sous forme de méthode. La méthode d’anniversaire va avec l’âge qu’elle modifie, ce qui permet de garder la règle à un seul endroit.
Imagine une classe comme un plan de construction. Beaucoup de maisons peuvent suivre un même plan, mais chacune possède son propre contenu. De même, deux animaux peuvent suivre la même définition et avoir des âges différents. Tu écris les noms des champs une seule fois ; chaque objet reçoit ses propres valeurs.
Lis une petite classe
public class Pet {
private String name;
private String species;
private int age;
public Pet(String name, String species, int age) {
this.name = name;
this.species = species;
this.age = age;
}
public void celebrateBirthday() {
this.age++;
}
}
Lis ce code de l’extérieur vers l’intérieur. public class Pet introduit le type et les accolades extérieures contiennent sa définition. Les trois premières déclarations décrivent l’état. Le bloc nommé Pet est un constructeur : il donne ses premières valeurs à un nouvel objet. celebrateBirthday est une méthode : elle augmente l’âge de l’objet courant. Les mots private et public contrôlent l’accès ; les exemples suivants les utilisent pour protéger l’état.
Les paramètres du constructeur sont des valeurs fournies lors de la création d’un objet. Dans this.age = age;, le côté gauche désigne le champ de l’objet et le côté droit le paramètre fourni. Le constructeur stocke cette donnée pour que l’objet puisse la mémoriser après la fin de sa construction.
Utilise une classe
Tu as déjà utilisé des classes de bibliothèque. Scanner décrit des objets qui lisent des données en entrée, ArrayList décrit des listes et un objet String propose des opérations comme length(). Une classe que tu écris suit le même principe : elle met un type utile à la disposition du reste de ton programme.
Sans Pet, un programme pourrait transmettre séparément un nom, une espèce et un âge à de nombreuses méthodes. Il devrait maintenir correctement chaque groupe de valeurs. Un objet Pet réunit les valeurs liées en une seule entité. Les méthodes de cet objet savent quel âge elles doivent utiliser.
Organise et nomme le code
Pour les fichiers source ordinaires, une classe publique nommée Pet est enregistrée dans Pet.java, en respectant les majuscules. Une classe Main distincte peut contenir la méthode main du programme, créer des animaux et appeler leurs méthodes. Pet n’a pas besoin de sa propre méthode main. Les classes d’un même paquetage sans nom peuvent s’utiliser entre elles sans importation ; les exemples simples placent ces classes dans un même dossier.
Utilise des noms en UpperCamelCase pour les classes, comme LibraryBook. Utilise lowerCamelCase pour les champs et les méthodes : pageCount nomme une donnée ; giveBack() nomme une action. Ces conventions aident le lecteur à reconnaître chaque élément, même si le compilateur autorise bien d’autres noms.
Points clés
- Une classe définit un type ; un objet est une instance créée pendant l’exécution du programme.
- Les champs contiennent l’état et les méthodes définissent le comportement.
- Les objets d’une même classe suivent la même définition et possèdent leurs propres valeurs de champs d’instance.
- Dans un fichier source ordinaire, le nom du fichier d’une classe publique correspond au nom de la classe.
1.2 Nouveaux objets et références qui les désignent
Créer un objet et déclarer une variable sont deux opérations différentes. Une variable te donne un nom par lequel accéder à un objet ; new crée l’objet auquel ce nom fera référence.
Lis une instruction de création d’objet
Pet luna = new Pet("Luna", "cat", 3);
Pet est le type de la variable et luna est son nom. new Pet(...) crée un nouvel objet et appelle un constructeur correspondant avec trois arguments. Le constructeur stocke le nom, l’espèce et l’âge. La référence obtenue est affectée à luna.
Une référence indique à Java quel objet utiliser. Il est utile de représenter une variable par un nom accompagné d’une flèche vers un objet. La variable n’est pas une deuxième copie de tous les champs de l’objet.
Appelle une méthode sur un objet précis
Le point dans luna.celebrateBirthday() relie une référence à une méthode à exécuter sur son objet. Une méthode qui renvoie une valeur peut la fournir à une autre expression :
luna.celebrateBirthday();
int years = luna.getAge();
System.out.println(years); // 4
Ici, getAge() est une méthode publique qui renvoie l’âge de l’animal. L’appel lié à l’anniversaire modifie l’état ; l’accesseur lit cet état. Pet.celebrateBirthday() échoue parce que cette méthode d’instance a besoin d’un animal précis. Le nom de la classe seul ne dit pas de quel anniversaire il s’agit.
Objets distincts et références partagées
Pet max = new Pet("Max", "dog", 5);
luna.celebrateBirthday();
System.out.println(luna.getAge()); // 5
System.out.println(max.getAge()); // 5
Luna avait déjà 4 ans, donc l’anniversaire suivant la fait passer à 5 ans. Max reste à 5 ans. Des âges égaux ne font pas d’eux un même objet : les deux expressions new ont créé des animaux distincts.
Considère maintenant une affectation sans new :
Pet other = luna;
other.celebrateBirthday();
System.out.println(luna.getAge()); // 6
L’affectation copie la référence vers Luna. Les deux noms donnent accès au même animal : une modification effectuée par other est donc visible par luna. Pour créer un deuxième animal, appelle new à nouveau.
Respecte les paramètres du constructeur
Les arguments doivent correspondre au nombre, à l’ordre et aux types des paramètres d’un constructeur déclaré. Si le seul constructeur disponible prend (String, String, int), new Pet() ne se compile pas. Java ne devine pas les valeurs manquantes. En revanche, inverser les deux chaînes se compile quand même : new Pet("cat", "Luna", 3) fournit les bons types mais pas les bonnes significations. Lis les noms des paramètres pour vérifier leur ordre.
Ces deux tentatives inachevées échouent pour des raisons différentes :
Pet a; // declaration only
// System.out.println(a.getAge()); // a has no assigned value
// Pet b = Pet("Bo", "cat", 2); // missing new
Une valeur doit être affectée à une variable locale avant son utilisation. Sans new, Java cherche une méthode nommée Pet, pas une expression de création d’objet. Une fois l’objet créé, l’afficher peut montrer un texte comme Pet@8bcc55f tant que tu ne fournis pas une méthode toString() lisible ; cette sortie ne signifie pas que la construction a échoué.
Points clés
- Utilise new avec des arguments qui correspondent à un constructeur disponible.
- La notation pointée appelle une méthode d’instance sur l’objet désigné par une référence.
- Une nouvelle expression new crée un autre objet ; l’affectation d’une référence permet de partager un objet existant.
- Des arguments de même type peuvent être inversés sans erreur du compilateur : vérifie donc leur signification.
- Une déclaration locale seule ne crée aucun objet et ne donne à la variable aucune valeur utilisable.
2Champs et état initial d’un objet
Les objets ont besoin d’un endroit où conserver leurs données et d’un moyen fiable d’obtenir leurs premières valeurs. Les champs fournissent le stockage ; les constructeurs initialisent chaque nouvel objet. Tu choisiras les types des champs, distingueras l’état durable du travail local temporaire et suivras la construction, des valeurs par défaut à un objet prêt à l’emploi. Tu proposeras ensuite plusieurs façons utiles de créer un même type d’objet tout en conservant l’initialisation et les vérifications communes à un seul endroit.
2.1 Les données qu’un objet mémorise
Un objet a besoin d’un champ pour chaque valeur qu’il doit mémoriser entre deux appels de méthode. Choisis ces valeurs avant d’écrire les méthodes : elles constituent l’état durable de l’objet.
Déclare des champs de types adaptés
Un champ se trouve entre les accolades de la classe, mais en dehors de tout constructeur et de toute méthode. Une déclaration comporte nécessairement un type et un nom ; elle peut aussi comporter un modificateur d’accès et un initialiseur.
private String title;
private int pageCount;
private boolean lentOut = false;
String convient au texte, int au dénombrement par un entier et boolean à une condition dont la réponse est oui ou non. Les champs peuvent aussi utiliser des types définis par des classes comme ArrayList<String>. Ces exemples utilisent private ; omettre le modificateur donne un accès de paquetage, pas un accès privé.
Chaque objet reçoit une copie distincte de chaque champ d’instance. Deux objets Rectangle ont chacun un champ width et un champ height, même si les déclarations n’apparaissent qu’une fois dans la classe.
Les valeurs par défaut ne sont pas toujours des valeurs initiales utilisables
| Type du champ | Valeur par défaut |
|---|---|
int, long | 0 |
double | 0.0 |
boolean | false |
Types définis par des classes, dont String et ArrayList | null |
Une valeur par défaut est affectée à un champ lorsque l’espace de stockage de l’objet est créé. Elle peut ne pas convenir à l’usage de l’objet. Un champ de type liste dont la valeur est null n’est pas une liste vide : tu dois encore créer la liste avant d’y ajouter un élément.
Les variables locales ne reçoivent pas de telle valeur par défaut. Dans une méthode, int total; suivi de System.out.println(total); ne se compile pas parce qu’aucune valeur n’a été affectée à total. Distingue bien la règle des champs de celle des variables locales.
Décide ce qui doit durer
| Type de variable | Où elle est déclarée | À quoi elle sert |
|---|---|---|
| Champ d’instance | Dans la classe, en dehors des méthodes | Valeurs mémorisées par un objet |
| Paramètre | Dans l’en-tête d’un constructeur ou d’une méthode | Données fournies pour cet appel |
| Variable locale | Dans un bloc de méthode ou de constructeur | Travail temporaire pour cet appel |
Un champ reste associé à son objet. Un paramètre est disponible pendant son appel et une variable locale est disponible dans son bloc pendant l’exécution de cet appel. Si un compteur doit conserver son compte d’un appel à l’autre, le compte doit être placé dans un champ. Un sous-total temporaire utilisé pour un calcul peut être local.
Stocke les données ; calcule les valeurs dérivées
public class Rectangle {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double area() {
return this.width * this.height;
}
}
Les dimensions sont en centimètres, donc area() renvoie une aire en centimètres carrés. Stocker l’aire dans un champ distinct créerait une valeur supplémentaire à mettre à jour chaque fois que l’une des dimensions change. La calculer à partir des dimensions garantit la cohérence du résultat.
Utilise un champ d’instance final pour une valeur affectée une seule fois, comme private final String title;. Donne-lui une valeur dans sa déclaration ou dans chaque constructeur. final empêche toute réaffectation. static a un sens différent : il crée un champ de classe partagé. Ajouter static au nom d’un animal ferait partager une seule variable de nom à plusieurs animaux.
Points clés
- Les champs d’instance sont déclarés en dehors des méthodes et mémorisent l’état de chaque objet.
- Les champs reçoivent des valeurs par défaut ; les variables locales doivent recevoir une valeur avant leur utilisation.
- Choisis des champs pour les données durables et des variables locales pour le travail temporaire.
- Calcule les valeurs qui découlent des champs stockés pour éviter les copies incohérentes.
- Un champ d’instance final reçoit une valeur une seule fois ; un champ statique est partagé par la classe.
- Un champ de type liste qui vaut null a encore besoin d’un objet liste avant de pouvoir être utilisé.
2.2 Des arguments aux champs initialisés
Un constructeur initialise un objet lorsque new le crée. Son nom doit correspondre à celui de la classe et il n’a pas de type de retour. Même void transformerait la déclaration en méthode.
Transfère les données dans l’état
public Pet(String name, String species, int age) {
this.name = name;
this.species = species;
this.age = age;
}
Un constructeur accepte généralement des données sous forme de paramètres et les stocke dans des champs. Ici, chaque paramètre porte le même nom que son champ. Le nom seul age désigne le paramètre ; this.age désigne le champ de l’objet en cours de création. L’affectation lit la valeur fournie à droite et l’écrit dans le champ à gauche.
Pour new Pet("Luna", "cat", 3), les champs du nouvel objet reçoivent d’abord les valeurs par défaut : null, null et 0. Le constructeur reçoit ensuite les trois arguments et remplace ces valeurs. Une fois la construction terminée, new produit la référence que l’appelant stocke.
Deux bogues qui se compilent
public Pet(String name, String species, int age) {
name = name;
this.species = species;
this.age = age;
}
Les deux occurrences de name désignent le paramètre : la première ligne affecte donc au paramètre sa propre valeur. Le nom de l’objet reste à null. Le code est valide, d’où l’importance de vérifier les valeurs du nouvel objet.
Une déclaration dans le constructeur provoque un problème similaire :
String nick = initialNick;
Si un champ nommé nick existe déjà, cette ligne crée une variable locale de même nom. La variable locale disparaît à la fin de la construction. Écris this.nick = initialNick; pour stocker la donnée dans le champ ; ne répète pas le type.
Sache quand un constructeur sans argument existe
Si une classe ne déclare aucun constructeur, Java fournit un constructeur par défaut sans paramètre. Pour une classe simple, ses champs conservent leurs valeurs initiales déclarées ou leurs valeurs par défaut. Dès que tu déclares un constructeur, Java cesse de fournir ce constructeur par défaut.
Une classe qui possède seulement Pet(String name, String species, int age) ne peut donc pas être instanciée avec new Pet(). Ajoute un constructeur explicite sans argument uniquement lorsqu’il existe un état initial utile pour celui-ci. Fais aussi attention à public void Pet(...) : c’est une méthode, elle ne fournit donc pas du tout le constructeur souhaité.
Définis aussi les valeurs initiales internes
Tous les champs n’ont pas besoin de provenir d’un argument. Un nouveau livre peut toujours commencer avec this.lentOut = false;. Une classe qui possède une liste peut l’initialiser ainsi, après importation de ArrayList :
private ArrayList<String> tracks;
public Playlist() {
this.tracks = new ArrayList<>();
}
La liste vide est prête pour add. Laisser tracks à null provoque ensuite l’échec de tracks.add(...) avec une NullPointerException.
Un initialiseur de champ s’exécute avant le corps du constructeur. Si private int score = 10; est suivi de this.score = 5; dans le constructeur, le score de l’objet terminé est 5. Teste les valeurs après la construction, pas seulement les valeurs écrites à côté des déclarations de champs. Les constructeurs doivent aussi appliquer les mêmes règles de validation que les modifications ultérieures, afin que l’état initial soit valide.
Points clés
- Un constructeur porte le nom de la classe et n’a pas de type de retour.
- Utilise this.field = parameter lorsque les noms sont identiques.
- Ni l’affectation d’un paramètre à lui-même ni la création d’une variable locale n’initialise le champ visé.
- Java ne fournit un constructeur par défaut que si la classe ne déclare aucun constructeur.
- Initialise l’état interne, comme les listes vides, et applique les règles de validation pendant la construction.
2.3 Plusieurs façons de construire un même type d’objet
Une classe peut proposer plusieurs façons utiles de créer un objet. La surcharge de constructeurs consiste à déclarer des constructeurs dont les listes de paramètres sont différentes.
Distingue les constructeurs par leurs paramètres
Java distingue les constructeurs par le nombre, les types et l’ordre de leurs paramètres. Les noms des paramètres ne permettent pas de les distinguer. Box(String label) et Box(String name) décrivent la même liste de paramètres : ils ne peuvent donc pas être tous deux déclarés dans une même classe.
Un animal peut être créé avec un âge ou comme nouveau-né :
public Pet(String name, String species, int age) {
this.name = name;
this.species = species;
this.age = age;
}
public Pet(String name, String species) {
this(name, species, 0);
}
new Pet("Pip", "rabbit") sélectionne le constructeur à deux paramètres. Ce constructeur fournit 0 pour l’âge manquant et appelle le constructeur à trois paramètres. L’état du nouvel objet contient finalement "Pip", "rabbit" et 0.
Chaîne l’initialisation sur le même objet
Dans un constructeur, this(...) appelle un autre constructeur de la même classe. Le constructeur le plus court choisit des valeurs par défaut ; le constructeur le plus complet effectue l’initialisation commune. Les vérifications placées dans cette initialisation s’appliquent aux deux façons de construire l’objet.
Compare deux lignes qui se ressemblent :
| Ligne dans un constructeur | Effet |
|---|---|
this(name, species, 0); | Initialise l’objet courant par l’intermédiaire d’un autre constructeur |
new Pet(name, species, 0); | Crée un animal distinct |
La deuxième ligne ne remplit pas les champs de l’objet courant. Si son résultat n’est jamais stocké, cet animal supplémentaire est abandonné. Les champs de l’animal courant peuvent encore valoir null.
Suis une chaîne avant de suivre le reste du code
Une horloge peut proposer minuit comme valeur par défaut :
public Clock() {
this(0, 0);
}
public Clock(int hours, int minutes) {
this.hours = hours;
this.minutes = minutes;
}
Pour new Clock(), entre dans le constructeur sans argument, suis this(0, 0) et affecte les deux champs dans le constructeur à deux arguments. L’exécution revient ensuite au constructeur sans argument. Cela crée une seule horloge, pas deux. Un appel à new Clock(9, 5) démarre directement dans le constructeur le plus complet.
Garde une chaîne valide et claire
Un constructeur peut contenir au maximum un appel this(...). La chaîne doit finir par atteindre une initialisation qui ne rappelle pas un constructeur de la chaîne : deux constructeurs qui délèguent l’un à l’autre provoquent une erreur de compilation due à un appel récursif de constructeur.
Placer this(...) en premier est un style clair qui fonctionne dans toutes les versions de Java. Dans Java 24 et les versions antérieures sans fonctionnalités en avant-première, l’appel doit être en premier. Java 25 autorise des instructions avant cet appel, par exemple pour calculer ou vérifier des arguments. Ces instructions ne peuvent ni lire les champs d’instance de l’objet courant ni appeler ses méthodes d’instance ; les affectations aux champs déclarés dans la classe sans initialiseur dans leur déclaration sont autorisées.
Propose des surcharges parce que les appelants disposent de différentes données utiles. Une horloge réglée à minuit a un sens ; un livre sans titre n’en a pas forcément. L’existence d’un constructeur complet ne crée automatiquement aucune surcharge plus courte.
Points clés
- Les constructeurs surchargés se distinguent par leurs listes de paramètres, pas par les noms de ces paramètres.
- L’appel this(...) délègue à un autre constructeur sur le même objet.
- Garde l’initialisation et les vérifications communes dans un seul chemin de construction.
- Une chaîne de constructeurs ne doit pas revenir à un constructeur qui en fait déjà partie.
3Méthodes qui lisent et modifient l’état
Un objet utile peut répondre à des questions sur lui-même et effectuer des actions qui modifient son état. Les méthodes d’instance placent ces opérations à côté des champs qu’elles utilisent. Tu suivras les modifications instruction par instruction, géreras le passage d’une heure à l’autre sur une horloge et renverras des valeurs utilisables par d’autres parties du code. Tu décideras aussi quelles données appartiennent à chaque objet et quelles données ou opérations appartiennent à la classe, afin que les objets distincts restent indépendants.
3.1 Calculs, modifications et traces des états
Une méthode d’instance s’exécute pour un objet précis. Déclare-la sans static et utilise les champs de cet objet avec des noms comme this.width. Décide de ce dont l’appelant a besoin : une modification de l’état, un résultat renvoyé ou les deux.
Renvoie les résultats des calculs ; rends explicites les modifications de l’état
Pour un rectangle dont les dimensions sont stockées en centimètres :
public double area() {
return this.width * this.height;
}
public double perimeter() {
return 2 * (this.width + this.height);
}
public void scale(double factor) {
this.width = this.width * factor;
this.height = this.height * factor;
}
Un rectangle de côtés 3,0 et 4,0 a une aire de 12,0 centimètres carrés et un périmètre de 14,0 centimètres. scale(2) fait passer les côtés à 6,0 et 8,0. Les appels suivants renvoient une aire de 48,0 et un périmètre de 28,0. Chaque méthode lit les champs actuels : aucune aire stockée n’a donc besoin d’être mise à jour.
area() renvoie un nombre qui peut être stocké ou utilisé dans un calcul. Si elle ne faisait qu’afficher le nombre et avait le type de retour void, l’appelant ne pourrait pas écrire double twice = r.area() * 2;. Laisse l’affichage à l’appelant lorsque le rôle d’une méthode est de calculer une valeur.
Mets à jour les champs liés dans l’ordre
La méthode advance() d’une horloge doit gérer le passage à l’heure et au jour suivants :
public void advance() {
this.minutes++;
if (this.minutes == 60) {
this.minutes = 0;
this.hours++;
if (this.hours == 24) {
this.hours = 0;
}
}
}
À 23 h 58, le premier appel atteint 23 h 59 et saute les deux blocs de remise à zéro. L’appel suivant atteint brièvement la minute 60, la remet à 0, fait passer l’heure à 24, puis la remet à 0. L’état final est 00 h 00. Un appel de plus donne 00 h 01.
Suis les objets séparément
Écris une ligne après chaque instruction et une colonne pour les champs de chaque objet. Ne modifie que l’objet désigné par le receveur de l’appel. Pour des animaux âgés de 2 et 7 ans, deux anniversaires pour le premier et setAge(1) pour le second donnent finalement les âges 4 et 1. N’exécute pas le corps d’une méthode pour toutes les instances simplement parce qu’elles partagent une classe.
Une déclaration locale peut masquer le champ que tu voulais mettre à jour. public void reset() { int count = 0; } ne crée qu’une variable temporaire. this.count = 0; remet à zéro le compte durable.
Réutilise les méthodes et complète les chemins de retour
Dans une méthode d’instance, area() et this.area() appellent la méthode de calcul de l’aire du même objet. Une méthode de description peut réutiliser ce calcul au lieu de copier son expression. Une méthode peut aussi modifier l’état et renvoyer une indication de réussite, comme lend() lorsqu’elle marque un livre comme emprunté et renvoie true.
Une méthode dont le type de retour est différent de void ne peut pas simplement atteindre sa fin sans renvoyer une valeur compatible. Si get() ne renvoie une valeur que dans if (count > 0), que se passe-t-il lorsque le compte vaut 0 ? Ajoute le chemin de retour nécessaire ou lève une exception pour une valeur que la méthode rejette. Un chemin qui lève une exception ne rend pas la main à l’appelant et n’a pas besoin de valeur de retour.
Points clés
- Les méthodes d’instance lisent ou modifient l’état de l’objet sur lequel elles sont appelées.
- Renvoie les valeurs calculées pour que les appelants puissent les utiliser dans des expressions.
- Suis les instructions dans l’ordre, en gardant séparés les champs de chaque objet.
- Les méthodes qui gèrent un passage à la valeur suivante doivent ramener chaque champ concerné dans son intervalle autorisé.
- Réutilise d’autres méthodes du même objet en les appelant directement ou avec this.
- Une méthode qui renvoie une valeur doit en fournir une sur chaque chemin qui se termine normalement.
3.2 Membres propres aux objets et membres de classe partagés
Demande-toi à qui appartient une valeur ou une opération avant de décider d’utiliser static. L’âge d’un animal appartient à cet animal. Le nombre de tous les animaux créés appartient à la classe entière.
L’objet courant est this
Dans un constructeur ou une méthode d’instance, this désigne l’objet en cours de construction ou celui qui reçoit l’appel. Dans this.age++, il indique l’objet dont l’âge change. Dans this.name = name, il distingue le champ d’un paramètre de même nom. this(...) est la forme utilisée pour chaîner les constructeurs.
Une méthode statique n’a pas d’objet courant : this ne peut donc pas y être utilisé. Elle peut toutefois créer un objet ou recevoir une référence et l’utiliser pour appeler des méthodes d’instance.
Champs partagés et champs propres aux objets
public class Counter {
private int count;
private static int created = 0;
public Counter() {
this.count = 0;
created++;
}
public void increment() {
this.count++;
}
public int getCount() {
return this.count;
}
public static int getCreated() {
return created;
}
}
Après deux appels à new Counter(), il y a deux champs count distincts, initialement égaux à 0, et un champ created égal à 2. Incrémenter le premier compteur fait passer son compte à 1 ; celui du second reste à 0. Counter.getCreated() renvoie toujours 2, car aucun nouvel objet n’a été construit.
Utilise un objet depuis main
public static void main(String[] args) {
Counter c = new Counter();
c.increment();
System.out.println(c.getCount());
}
La méthode main classique est statique. Un appel à increment() seul à cet endroit n’aurait pas d’objet cible et ne se compilerait pas. La variable c fournit cette cible. Rendre count statique pour faire disparaître l’erreur changerait la conception : tous les compteurs partageraient alors un seul compte.
| Type de méthode | Accès direct disponible |
|---|---|
| Méthode d’instance | Ses membres d’instance et les membres statiques de la classe |
| Méthode statique | Membres statiques ; membres d’instance par une référence vers un objet |
Java 25 prend aussi en charge des formes de main sous forme de méthode d’instance, mais l’en-tête statique classique reste valide. Ces exemples l’utilisent systématiquement.
Choisis les méthodes et les constantes avec soin
Une opération qui a besoin des champs d’un objet devrait être une méthode d’instance. Une opération qui dépend uniquement de ses paramètres peut être statique, comme une méthode auxiliaire qui convertit un nombre total de minutes en heures. Les appels statiques utilisent normalement le nom de la classe : Math.sqrt(16) ou Counter.getCreated().
Une valeur fixe partagée est généralement déclarée comme une constante :
public static final int MAX_CELSIUS = 30;
public la rend accessible aux appelants, static donne à la classe un champ partagé unique et final empêche sa réaffectation. Par convention, UPPER_SNAKE_CASE indique une constante. C’est une exception courante à la règle qui rend les champs privés. N’utilise pas static pour les noms, les dimensions ou tout autre élément d’état ordinaire qui doit différer d’un objet à l’autre.
Points clés
- La référence this désigne l’objet courant dans le code d’instance.
- Les membres statiques appartiennent à la classe ; les membres d’instance appartiennent à chaque objet.
- Une méthode statique a besoin d’une référence vers un objet pour utiliser des membres d’instance.
- Corrige les erreurs de contexte statique en fournissant l’objet approprié lorsque l’état appartient à un objet.
- Un champ public static final fournit couramment une constante partagée.
4Accès contrôlé et état valide
Une classe devrait contrôler les valeurs qui peuvent entrer dans son état. Les champs privés et les méthodes publiques lui permettent de vérifier chaque modification et de fournir aux appelants des opérations utiles. Tu choisiras des niveaux d’accès, écriras des accesseurs et des mutateurs lorsqu’ils sont utiles et protégeras des règles comme un intervalle de températures autorisé. Tu verras aussi pourquoi une liste privée peut être exposée par un accesseur et comment empêcher le code extérieur de contourner les vérifications de la classe.
4.1 État privé et interface publique
L’encapsulation rassemble l’état d’un objet et le code qui le contrôle. Les champs sont généralement privés, tandis que les appelants utilisent des opérations publiques. Cela masque les détails du stockage et donne à la classe un endroit où faire appliquer ses règles.
Choisis un niveau d’accès
| Accès | Qui peut utiliser le membre |
|---|---|
private | Le code de la même classe |
| Aucun modificateur | Le code du même paquetage |
protected | Le même paquetage, ainsi que les sous-classes selon les règles d’accès de Java |
public | Le code qui peut accéder au type déclarant |
Un paquetage regroupe des classes. Les exemples simples placent des classes ordinaires ensemble sans déclaration package, dans un seul paquetage sans nom. L’accès de paquetage résulte de l’omission du modificateur ; il n’existe pas de mot-clé d’accès package à ajouter à un champ.
Commence par l’accès utile le plus restrictif. Rends les champs privés, les constructeurs et les opérations nécessaires aux autres classes publics, et les méthodes auxiliaires internes privées. Les constantes publiques sont une exception courante pour les champs.
Confie à la classe le contrôle des modifications
Si Pet déclare private int age;, une classe Main distincte ne peut pas effectuer l’affectation luna.age = -5;. Le compilateur rejette cet accès. Un appel comme luna.setAge(-5) peut être autorisé, car la méthode publique appartient à Pet et peut décider de stocker ou non l’argument.
Un champ public permettrait à tout appelant de contourner cette méthode. Lorsque toutes les modifications passent par le code de la classe, les vérifications peuvent être regroupées à un seul endroit. L’accès privé seul ne valide pas un âge ; les méthodes doivent aussi effectuer les vérifications.
Garde l’interface publique stable
Supposons qu’une horloge stocke initialement les champs distincts hours et minutes. Les appelants utilisent getHours() et getMinutes(). Tu remplaces ensuite les champs par une seule valeur minutesSinceMidnight :
public int getHours() {
return this.minutesSinceMidnight / 60;
}
public int getMinutes() {
return this.minutesSinceMidnight % 60;
}
Avec 615 minutes stockées, la division renvoie 10 et le reste vaut 15. L’horloge indique 10 h 15 par les mêmes méthodes. Le code des appelants n’a pas besoin d’être réécrit, car il dépendait des opérations publiques, pas de la façon dont l’état était stocké. Cette liberté de modifier les éléments internes est le masquage de l’information.
L’accès dépend des classes, pas des objets individuels
Le code dans Pet peut lire un champ privé d’un autre objet Pet. L’autorisation d’accès vient du fait que le code se trouve dans la classe. Une autre classe de premier niveau n’obtient pas cette autorisation en possédant une référence vers un animal ou en se trouvant dans le même dossier.
Pour les déclarations ordinaires de classes de premier niveau, les choix d’accès sont public ou aucun modificateur. Une déclaration private class Pet au premier niveau est interdite. Une classe publique de premier niveau va dans le fichier source correspondant, et un fichier source ordinaire contient au maximum une classe publique de premier niveau.
Les champs privés constituent une frontière dans la conception du programme. Ils empêchent le reste du code ordinaire de dépendre directement des champs internes, mais ne permettent pas de garder une valeur secrète pour une personne qui peut examiner le programme. Utilise-les pour contrôler l’interface de ta classe et protéger son état.
Points clés
- Les champs privés et les opérations publiques conservent le contrôle de l’état dans la classe.
- Omettre un modificateur d’accès donne un accès de paquetage.
- Les méthodes publiques permettent de modifier le stockage interne sans modifier le code des appelants.
- L’accès privé est vérifié par classe : le code dans la classe peut donc accéder aux champs d’une autre instance.
- Les classes ordinaires de premier niveau utilisent l’accès public ou l’accès de paquetage.
4.2 Des méthodes d’accès adaptées à la classe
Une classe peut permettre aux appelants de lire ou de modifier certaines parties de son état par l’intermédiaire de méthodes. Décide des opérations que la classe devrait proposer avant de créer des méthodes d’accès pour chaque champ.
Renvoie des valeurs avec des accesseurs
Un accesseur, aussi appelé méthode d’accès, renvoie des informations sans modifier l’objet. Un accesseur courant lit un champ :
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
Le type de retour correspond à l’information fournie. Un accesseur qui affiche une valeur et renvoie void ne peut pas fournir de valeur à une expression comme pet.getAge() + 1. L’appelant devrait recevoir la valeur et décider comment l’utiliser.
Modifie certaines valeurs avec des mutateurs
Un mutateur, aussi appelé méthode de modification, reçoit une nouvelle valeur et met à jour l’état :
public void setName(String name) {
this.name = name;
}
this.name est le champ. name est le paramètre. Écrire name = name; se compile mais ne modifie aucun champ. Il n’y a pas de valeur de retour ici, car le rôle de ce mutateur est d’effectuer une modification.
Pour un animal âgé de 3 ans :
luna.setName("Lulu");
System.out.println(luna.getName() + " is " + luna.getAge());
// Lulu is 3
L’appelant ne touche jamais directement à un champ. Le mutateur modifie le nom et les accesseurs renvoient les valeurs actuelles que l’appelant peut combiner.
Respecte les noms attendus par les autres codes Java
| Champ | Accesseur | Mutateur, si nécessaire |
|---|---|---|
pageCount | getPageCount() | setPageCount(int pageCount) |
name | getName() | setName(String name) |
lentOut | isLentOut() | setLentOut(boolean lentOut) |
Mets en majuscule la première lettre du nom du champ après get, set ou le préfixe booléen habituel is. Un nom comme getname() peut se compiler, mais il ne suit pas la convention attendue par les outils et les autres programmeurs.
N’expose que les opérations utiles
Le titre d’un livre peut avoir un accesseur et aucun mutateur, car les appelants devraient pouvoir le lire sans le remplacer. Un champ privé final peut garantir qu’il ne reçoit une valeur qu’une fois. Un compteur interne peut n’avoir besoin ni d’accesseur ni de mutateur si seule la classe l’utilise.
Un mutateur sans vérification peut accepter la même valeur dommageable qu’un champ public. Ajoute des vérifications lorsqu’une modification est soumise à des restrictions. Envisage aussi une méthode d’action : celebrateBirthday() exprime l’augmentation de l’âge d’un an et lend() exprime une tentative de prêt. lend() peut examiner l’état courant et refuser un deuxième prêt. Un mutateur peut aussi effectuer cette vérification ; le nom de l’action rend l’opération plus claire pour son appelant.
Un accesseur peut calculer un résultat. getArea() peut renvoyer le produit de la largeur par la hauteur sans aucun champ area.
Points clés
- Un accesseur renvoie une information ; un mutateur modifie une valeur donnée.
- Suis le modèle de nommage getName, setName et, pour les booléens, l’habituel isName.
- Ne donne aux champs que les méthodes d’accès dont les appelants ont besoin.
- Les méthodes d’action comme lend expriment clairement les comportements autorisés et peuvent vérifier les changements d’état.
4.3 Des règles qui résistent à chaque modification
Un invariant est une règle sur l’état d’un objet qui reste vraie après la construction et après chaque opération publique. Un thermostat peut autoriser des températures cibles de 5 °C à 30 °C. Chaque moyen de définir sa cible doit respecter cet intervalle.
Choisis comment traiter une entrée invalide
Trois réponses utiles consistent à conserver l’ancienne valeur, à ramener la valeur à une borne ou à lever une exception. Leurs effets sont différents : choisis donc une réponse claire pour chaque opération.
| Réponse | Résultat d’un appel invalide |
|---|---|
| Ignorer | L’ancienne valeur du champ reste inchangée |
| Écrêter | La borne autorisée la plus proche est stockée |
| Lever une exception | L’appel s’arrête avec une erreur comme IllegalArgumentException |
Pour un âge d’animal qui ne doit pas être négatif, un mutateur qui ignore les valeurs invalides peut effectuer l’affectation uniquement dans if (age >= 0). Si l’âge stocké est 4, setAge(-2) le laisse à 4. Il ne le remplace pas par 0.
Place les vérifications d’intervalle dans la classe
public static final int MIN_CELSIUS = 5;
public static final int MAX_CELSIUS = 30;
private int target;
public void setTarget(int celsius) {
if (celsius < MIN_CELSIUS) {
this.target = MIN_CELSIUS;
} else if (celsius > MAX_CELSIUS) {
this.target = MAX_CELSIUS;
} else {
this.target = celsius;
}
}
public void raise() {
setTarget(this.target + 1);
}
En partant de 20 °C, setTarget(35) stocke 30. setTarget(-3) stocke 5. Après setTarget(29), un appel à raise() stocke 30 ; un autre appel stocke encore 30. Réutiliser le mutateur empêche raise() de dépasser la borne supérieure.
Des vérifications uniquement dans Main ne peuvent pas protéger le thermostat. Un autre appelant pourrait les oublier. La classe doit vérifier la donnée à l’endroit où elle contrôle son stockage.
Valide aussi l’état initial
public Thermostat(int target) {
setTarget(target);
}
Avec ce constructeur qui effectue un écrêtage, new Thermostat(50) aboutit à 30 °C. Affecter directement this.target = target; autoriserait un état initial invalide de 50. Une méthode privée de vérification partagée est une autre façon de réutiliser la validation dans les constructeurs et les méthodes ultérieures.
Lever une exception est utile lorsqu’un argument invalide révèle une erreur de programmation. Par exemple, un constructeur peut rejeter un compte négatif avec throw new IllegalArgumentException("count must not be negative");. L’objet n’est pas construit avec succès, donc aucun objet terminé invalide n’est transmis à l’appelant. Ignorer une entrée est plus simple mais silencieux ; l’appelant peut avoir besoin d’un autre moyen de remarquer que rien n’a changé.
Garde les données internes mutables à l’intérieur
Une liste privée peut tout de même être exposée si un accesseur renvoie la liste originale. Un appelant pourrait alors ajouter ou supprimer des éléments sans utiliser les méthodes de la classe, en contournant une règle de taille maximale.
Pour un champ ArrayList<String> nommé tracks, return new ArrayList<>(this.tracks); fournit une liste distincte contenant les mêmes chaînes. Modifier cette liste renvoyée ne change pas la liste interne. Des opérations comme addTrack(String title) permettent de garder les modifications de la liste dans la classe et d’en vérifier les règles avant de les accepter.
Points clés
- Un invariant reste vrai après la construction et après chaque opération publique.
- Ignorer une entrée invalide, l’écrêter et lever une exception sont des réponses différentes.
- Chaque constructeur et chaque méthode qui modifie l’état doivent préserver les mêmes règles.
- Réutilise la validation pour qu’aucune voie de modification ne puisse la contourner.
- Renvoyer une liste interne mutable permet aux appelants de contourner les vérifications de la classe.
- Une copie d’une liste interne de chaînes protège la liste originale des modifications extérieures de la liste.
5Objets lisibles et classes complètes
Des descriptions lisibles des objets facilitent l’utilisation et la vérification d’une classe. Une méthode toString fournit ce texte chaque fois qu’un objet est affiché ou concaténé à une chaîne. Tu écriras la méthode avec le bon en-tête, puis tu réuniras champs, constructeurs, méthodes et validation dans une classe complète. À partir d’une courte description, tu transformeras les exigences en code et testeras les appels ordinaires, les actions répétées et les cas limites.
5.1 Une description d’objet renvoyée sous forme de texte
Un objet utile devrait être facile à examiner sous forme de texte. La méthode Java intégrée toString() renvoie un nom de classe, un signe @ et un code de hachage hexadécimal, par exemple Pet@8bcc55f. Un paquetage nommé fait partie du nom de la classe. Le texte du code de hachage varie et donne généralement peu d’informations sur l’état de l’objet.
Renvoie une description lisible
@Override
public String toString() {
return this.name + " (" + this.species + ", "
+ this.age + " years)";
}
Pour Luna, une chatte âgée de 3 ans, la chaîne renvoyée est "Luna (cat, 3 years)". La méthode lit les champs et construit une chaîne. Elle ne modifie pas l’animal et n’affiche rien à l’écran.
@Override demande au compilateur de vérifier que la déclaration remplace bien une méthode existante. Cela permet de détecter des erreurs comme écrire tostring avec un s minuscule. L’annotation ne formate pas le résultat à ta place ; c’est l’expression de retour qui détermine le texte.
Reconnais les appels automatiques
System.out.println(luna);
String label = "Pet: " + luna;
String details = luna.toString();
La première ligne affiche la description lisible de l’animal. La deuxième construit "Pet: Luna (cat, 3 years)". La troisième demande explicitement la même description et la stocke sans l’afficher. Lorsqu’une ArrayList d’animaux est affichée, son affichage utilise la méthode toString() de chaque animal entre les crochets de la liste.
La conversion automatique explique pourquoi il est important de renvoyer du texte. L’appelant peut afficher, stocker ou concaténer le résultat. Une méthode qui ne fait qu’afficher ne peut pas fournir la chaîne dont tous ces appelants ont besoin.
Respecte l’en-tête de la méthode
| Déclaration | Résultat |
|---|---|
public String toString() | Fournit la description de l’objet |
public String tostring() | Déclare une méthode différente ; @Override détecte l’erreur |
public String toString(int width) | Déclare une surcharge ; l’affichage automatique ne l’appelle pas |
public void toString() | Échoue : elle entre en conflit avec la méthode existante qui renvoie une String |
Utilise l’en-tête exact sans argument et inclus l’annotation. Une surcharge avec paramètres peut être une méthode distincte valide, mais l’affichage d’un objet ne fournit pas ces paramètres.
Formate les valeurs sans les modifier
Une horloge a besoin d’heures et de minutes à deux chiffres. Dans sa méthode toString() :
return String.format(java.util.Locale.US,
"%02d:%02d", this.hours, this.minutes);
Pour 9 heures et 5 minutes, la chaîne est "09:05". Chaque %02d formate un entier sur au moins deux positions, en ajoutant un zéro initial si nécessaire. String.format(java.util.Locale.US, "%.2f", 7.5) renvoie "7.50". Fournir les paramètres régionaux rend la sortie avec point décimal indépendante des paramètres régionaux de formatage par défaut de l’ordinateur.
Garde une description assez courte pour être lue pendant le débogage. Elle peut révéler un état non initialisé : concaténer un champ de nom valant null à une chaîne produit le texte "null", ce qui te ramène à l’initialisation. La description devrait rendre compte de l’état courant : afficher deux fois l’objet ne devrait donc pas faire avancer une horloge ni fêter un anniversaire.
Points clés
- Écris public String toString() sans paramètre et renvoie un texte lisible.
- L’annotation @Override permet au compilateur de vérifier que la méthode remplace une méthode existante.
- Afficher un objet et le concaténer à une chaîne utilisent automatiquement toString.
- Ne modifie pas l’état dans toString et laisse l’appelant décider où va le texte.
- String.format peut compléter des valeurs et utiliser des paramètres régionaux explicites pour obtenir une sortie prévisible.
5.2 D’une exigence à une classe testée
Commence par déterminer ce qu’un objet doit mémoriser, ce que les appelants peuvent lui demander de faire et quels états doivent être autorisés. Transforme ensuite chaque élément en champs, constructeurs et méthodes.
Tire la conception d’une description
« Un livre de bibliothèque a un titre, un auteur et un nombre de pages. Il peut être prêté et rendu. Il ne peut pas être prêté à nouveau tant qu’il est déjà en prêt. »
Utilise LibraryBook comme nom de classe. Stocke les trois valeurs descriptives et un état de prêt booléen. Le titre, l’auteur et le nombre de pages restent fixes : rends-les donc final. L’état du prêt change par des actions qui ont un sens. Un mutateur pour chaque champ est inutile.
Construis la classe complète
public class LibraryBook {
private final String title;
private final String author;
private final int pages;
private boolean lentOut;
public LibraryBook(String title, String author, int pages) {
this.title = title;
this.author = author;
this.pages = pages;
this.lentOut = false;
}
public boolean isLentOut() {
return this.lentOut;
}
public boolean lend() {
if (this.lentOut) {
return false;
}
this.lentOut = true;
return true;
}
public void giveBack() {
this.lentOut = false;
}
@Override
public String toString() {
String status = this.lentOut ? "lent out" : "available";
return this.title + " by " + this.author + ", "
+ this.pages + " pages, " + status;
}
}
Le constructeur rend le livre disponible. lend() vérifie l’état existant avant de le modifier ; renvoyer false lors d’un deuxième prêt préserve la règle. giveBack() rend le livre disponible. L’accesseur indique son état et toString() décrit le livre entier sans le modifier.
Écris les résultats attendus avant d’exécuter les appels
Dans la méthode main classique d’une classe Main distincte :
LibraryBook b = new LibraryBook("Night Train", "A. Rivera", 320);
System.out.println(b); // Night Train by A. Rivera, 320 pages, available
System.out.println(b.lend()); // true
System.out.println(b.lend()); // false
b.giveBack();
System.out.println(b.lend()); // true
La deuxième tentative de prêt est essentielle : une méthode qui définit toujours l’indicateur et renvoie true réussirait le premier appel mais échouerait à cette vérification. Teste l’état ainsi que les valeurs de retour avec isLentOut(). Essaie aussi un deuxième livre pour vérifier que le prêt de l’un laisse l’autre disponible.
Teste les points où le comportement change
Couvre chaque constructeur et chaque méthode publique. Pour les vérifications d’intervalle, essaie les deux bornes et des valeurs juste à l’extérieur. Pour une horloge, vérifie le passage à l’heure suivante et le passage à minuit. Pour un mutateur qui rejette ou ignore une entrée invalide, vérifie qu’elle a l’effet annoncé sur l’ancien état. Écris d’abord le résultat attendu pour qu’une sortie inattendue ne devienne pas discrètement ta nouvelle attente.
Construis par petites étapes : les champs et le constructeur d’abord, puis une description lisible, puis une opération et ses vérifications à la fois. Enregistre les classes publiques ordinaires dans des fichiers de noms correspondants, compile-les ensemble et exécute la classe qui contient main. Séparer les opérations du modèle de l’affichage à l’écran permet à la même classe de servir dans différents programmes.
Points clés
- Transforme les données à mémoriser en champs privés et les actions autorisées en méthodes.
- Écris les règles de l’état avant d’implémenter les constructeurs et les modifications.
- Utilise final pour les valeurs fixes propres à chaque objet et évite les mutateurs inutiles.
- Teste les valeurs de retour et l’état obtenu, notamment avec des appels répétés et des objets distincts.
- Vérifie les bornes et les entrées invalides ainsi que les valeurs ordinaires.
- Construis et teste une partie utile à la fois.
- Sépare le comportement du modèle du programme principal qui affiche les résultats.
Classes et objets en Java : exemples
1D’une classe à deux animaux
10 étapes
- 1IntroductionUn type pour les éléments de ton programme
Un programme sur les animaux de compagnie doit mémoriser ensemble un nom, une espèce et un âge. Une classe donne un type à ce groupe et propose des méthodes qui l’utilisent. Chaque objet est un animal créé à partir de cette définition.
Suis la différence entre la définition et les animaux qu’elle produit. Puis suis l’état de deux objets représentant des animaux et vois pourquoi une variable supplémentaire ne signifie pas toujours un objet supplémentaire.
- 2AnalogieUn plan et ses instances
Imagine une classe comme un plan de construction et ses objets comme les maisons construites à partir de ce plan. Le plan décrit ce que contient chaque maison, mais il n’est pas lui-même une maison.
Une définition
Petpeut décrire de nombreux animaux. Chacun possède des champs pour les mêmes types de données, mais l’un peut être un chat de trois ans et l’autre un chien de cinq ans. Définir les champs crée le plan ; la création d’objets fournit des instances concrètes. - 3ExempleRepère l’état et le comportement
Les champs
name,speciesetaged’un animal stockent son état. Pour Luna, leurs valeurs sont"Luna","cat"et3.La méthode
celebrateBirthday()définit un comportement. Son corps peut exécuterthis.age++;, ce qui modifie l’âge de l’animal receveur. La méthode fait partie de la définition de la classe ; la valeur qu’elle modifie appartient à un animal précis. - 4DéfiUne définition crée-t-elle un animal ?
Un programmeur écrit une classe
Petavec trois champs et une méthode d’anniversaire. Aucune expression de création d’objet n’a été exécutée. Combien d’objets représentant des animaux cette définition a-t-elle créés ?---reveal---
Aucun. La classe définit un type, ainsi que son état et son comportement possibles. Les objets apparaissent lorsque le programme les crée, par exemple avec
new Pet(...). Trois déclarations de champs décrivent trois données par animal, pas trois animaux. - 5ExempleCrée le premier objet
Lis
Pet luna = new Pet("Luna", "cat", 3);par parties.Pet lunadéclare une variable.new Pet(...)crée un animal et exécute le constructeur avec les trois arguments fournis.Le constructeur stocke les valeurs initiales. La référence produite par
newest affectée àluna, ce qui permet au code suivant d’accéder à cet objet. DéclarerPet luna;seul ne fournirait aucun objet sur lequel effectuer un appel. - 6ExplicationAppelle une méthode sur son objet receveur
Dans
luna.celebrateBirthday(), l’expression avant le point désigne l’objet receveur. La méthode d’anniversaire s’exécute pour Luna et fait passer son âge de 3 à 4 ans.int age = luna.getAge();récupère ensuite l’âge courant pour l’utiliser ailleurs.Pet.celebrateBirthday()ne peut pas choisir un animal : c’est une méthode d’instance et un nom de classe ne fournit aucun objet précis. - 7ExempleCrée un deuxième animal
Exécute maintenant
Pet max = new Pet("Max", "dog", 5);. Une deuxième expressionnewcrée un deuxième objet avec ses propres champs.Après un nouvel appel à
luna.celebrateBirthday(), Luna a 5 ans et Max a toujours 5 ans. Leurs âges égaux ne font pas d’eux un même objet. Un anniversaire ultérieur de Luna ne modifie que son âge, car l’âge de Max se trouve dans les champs d’un autre objet. - 8Point cléUne affectation peut partager un objet
Pet other = luna;copie la référence vers Luna. Cette instruction n’appelle pas de constructeur et ne copie pas ses champs dans un autre animal.Les noms
otheretlunadonnent maintenant accès au même objet. Appelerother.celebrateBirthday()fait passer l’âge de cet animal de 5 à 6 ans etluna.getAge()indique aussi 6. Compte les créations d’objets séparément des déclarations de variables. - 9DéfiSuis une référence partagée et un animal distinct
Deux animaux distincts ont initialement 1 an pour
aet 8 ans pourb. Le code exécutePet c = a; c.celebrateBirthday(); b.celebrateBirthday();. Quels âgesaetbindiquent-ils ?---reveal---
Ils indiquent 2 et 9.
cpartage l’objet dea, donc son appel augmente l’âge de cet animal. L’appel parbaugmente l’âge de l’animal distinct. La classe fournit le même comportement d’anniversaire aux deux, mais chaque appel a son propre objet receveur. - 10RécapitulatifLis attentivement les créations et les appels
Distingue trois rôles : la classe définit le type, chaque objet contient son propre état d’instance et une variable de référence donne accès à un objet.
Lorsque tu lis le code, repère chaque
new, fais correspondre ses arguments au constructeur et identifie l’objet receveur avant de suivre un appel de méthode. Une simple affectation de référence ajoute un moyen d’accéder à un objet existant. Un deuxièmenewcrée un objet distinct avec son propre état.
2Construis correctement l’état initial
14 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionDonne des données utiles à chaque nouvel objet
- 2ExplicationChoisis un état durable
- 3ExplicationDistingue les valeurs par défaut des valeurs utiles
- 4DéfiChoisis un champ ou une variable locale
- 5ExplicationLis l’en-tête du constructeur
- 6ExempleTransfère les paramètres dans les champs
- 7ConseilUne affectation valide qui ne stocke rien
- 8DéfiTrouve le champ inchangé
- 9LienCrée aussi les objets internes
- 10ExemplePropose une façon utile de construire l’objet par défaut
- 11ExplicationSuis un objet dans la chaîne
- 12DéfiDiagnostique une expression new trompeuse
- 13DéfiCombine un champ fixe avec une surcharge
- 14RécapitulatifVérifie chaque chemin vers un objet terminé
3Suis les modifications d’état et l’état partagé
13 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionSuis ce que chaque appel modifie
- 2ExplicationRenvoie une valeur à l’appelant
- 3ExempleModifie les dimensions stockées à l’aide d’un facteur
- 4DéfiVérifie le résultat renvoyé après une modification
- 5ExempleAvance jusqu’au passage à minuit
- 6ConseilCorrige une remise à zéro qui ne modifie pas l’état
- 7Point cléPrévois chaque retour normal
- 8ExplicationDistingue deux comptes d’un compteur partagé
- 9ExempleFournis un objet dans le code statique
- 10LienReconnais une constante
- 11DéfiSuis les deux types d’état
- 12DéfiTrouve pourquoi des objets distincts changent ensemble
- 13RécapitulatifAssocie chaque opération à son propriétaire
4Protège chaque voie de modification de l’état
14 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionRends la classe responsable de ses règles
- 2ExplicationMasque le champ derrière une opération
- 3ConseilChoisis l’accès utile le plus restrictif
- 4DéfiDétermine où l’accès privé fonctionne
- 5ExempleRenvoie une information avec un accesseur
- 6LienPropose des actions adaptées à l’objet
- 7DéfiPermets la lecture sans autoriser le remplacement
- 8ExplicationChoisis comment traiter une entrée invalide
- 9ExempleSuis l’écrêtage à la borne supérieure
- 10ExempleVérifie l’état initial
- 11DéfiSuis le traitement qui ignore la valeur au lieu de l’écrêter
- 12Point cléUne liste privée peut tout de même être exposée
- 13DéfiFerme les deux voies non vérifiées
- 14RécapitulatifExamine l’interface publique
5Construis et teste une classe utile
12 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionTransforme une exigence en comportement visible
- 2ExplicationUtilise l’en-tête exact de description
- 3ExempleRenvoie l’état courant sous forme de texte
- 4ConseilFormate une horloge sans la modifier
- 5DéfiCorrige l’affichage automatique
- 6ExempleChoisis les champs à partir de l’exigence
- 7ExempleDéfinis l’état initial
- 8ExempleApplique la règle avant la modification
- 9DéfiPrévois une séquence avant de l’exécuter
- 10LienTeste les cas qu’une exécution simple ne révèle pas
- 11DéfiDistingue la description de la modification
- 12RécapitulatifConstruis avec une garantie publique vérifiable
Classes et objets en Java : QCM
Série 1 : Crée des objets et lis leur état10 Questions Pratiques
Question 1 sur 10
Parcel pour créer plusieurs colis. Comment appelle-t-on un colis créé pendant l’exécution du programme ?Afficher la réponseMasquer la réponse
Parcel. La définition de la classe décrit les données et les opérations de tous ces objets ; elle n’est pas un autre nom pour un colis particulier. Une méthode est une opération que l’objet peut effectuer.Question 2 sur 10
Bell est stocké dans bell, et ring() est une méthode d’instance. Comment le programme doit-il faire sonner cette cloche ?Afficher la réponseMasquer la réponse
ring() sur l’objet désigné par bell. La variable avant le point fournit l’objet receveur dont une méthode d’instance a besoin. Bell.ring() désigne la classe : cet appel ne peut donc pas sélectionner cette cloche pour une méthode d’instance.Question 3 sur 10
private int attempts; sans initialiseur ni affectation dans le constructeur. Quelle valeur un nouvel objet stocke-t-il dans ce champ ?Afficher la réponseMasquer la réponse
int reçoit la valeur par défaut 0 avant toute initialisation explicite. La règle qui impose une affectation avant la lecture d’une variable locale non initialisée ne s’applique pas aux champs. null est la valeur par défaut des champs dont le type est une classe, pas d’un champ int.Question 4 sur 10
new Badge("Visitor"), getText() renvoie null. Le champ est private String text;, l’accesseur le renvoie et le corps du constructeur est text = text;. Comment le constructeur doit-il stocker son paramètre text ?Afficher la réponseMasquer la réponse
this.text = text; écrit la valeur fournie dans l’objet courant. Inverser l’affectation lit au contraire le champ encore à null dans le paramètre, et affecter le champ à lui-même le laisse aussi sans valeur définie.Question 5 sur 10
Ticket() { this(4); } et Ticket(int zones) { this.zones = zones + 1; }. Quelle valeur new Ticket() stocke-t-il dans zones ?Afficher la réponseMasquer la réponse
Question 6 sur 10
MinuteClock stocke les heures de 0 à 23 et les minutes de 0 à 59. advance() ajoute une minute en gérant le passage à l’heure suivante et à minuit. isMidnight() vérifie si l’heure est 00 h 00. En partant de 23 h 57, exécute advance(); advance(); advance(); if (isMidnight()) { advance(); } advance();. Quelle est l’heure finale ?Afficher la réponseMasquer la réponse
Question 7 sur 10
Lamp doit mémoriser son propre état allumé ou éteint. Comment cet état doit-il être déclaré ?Afficher la réponseMasquer la réponse
Question 8 sur 10
Bin est écrit int capacity; sans modificateur d’accès. Quel est son accès ?Afficher la réponseMasquer la réponse
private.Question 9 sur 10
Session possède private boolean active;. Les appelants doivent pouvoir le consulter, mais ne peuvent le modifier que par start() et stop(). Quel accesseur convient à cette conception ?Afficher la réponseMasquer la réponse
Question 10 sur 10
public String toString() { return "Ready"; }. Quel texte est produit par System.out.println("State: " + object); ?Afficher la réponseMasquer la réponse
"Ready" se combinent donc en "State: Ready". Définir une méthode toString() personnalisée sans argument remplace la description intégrée contenant la classe et le code de hachage ; Java n’ajoute pas ce texte intégré en préfixe.Série 2 : Vérifie l’initialisation et les modifications contrôlées10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Locker possède un champ occupied et une méthode release(). Quelle partie de cette classe décrit un comportement ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Panel stocke une largeur et une hauteur. Sa largeur peut changer et getArea() doit toujours indiquer l’aire actuelle. Comment l’aire doit-elle être représentée ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
public Sensor(int channel). Un appelant utilise new Sensor(). Pourquoi cet appel ne se compile-t-il pas ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
private int reading = 9;. Sa méthode est public void reset() { int reading = 0; }. Que renvoie un accesseur qui renvoie this.reading après reset() ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
minutesSinceMidnight, tandis que ses accesseurs renvoient toujours les mêmes valeurs. Pourquoi les appelants peuvent-ils conserver leurs appels existants aux accesseurs ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
setValue(25) puis setValue(8), quelles sont les valeurs stockées après chaque appel ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
Group doit contenir au maximum quatre noms. addName impose cette limite, mais Group(ArrayList<String> names) stocke directement la liste fournie et getNames() renvoie la liste interne. Quelle conception préserve la limite face aux modifications des appelants ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
toString() doit-elle utiliser ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
use() renvoie false s’il a déjà été utilisé ; sinon, elle active l’indicateur et renvoie true. reset() désactive l’indicateur. toString() ne fait que l’indiquer. Que renvoient les appels à use dans use(); println(pass); use(); reset(); use(); use(); ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 3 : Suis l’état des objets dans des séquences plus longues10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Marker possède un nom et setName. Exécute Marker a = new Marker("One"); Marker b = a; a = new Marker("Two"); b.setName("Three");. Que renvoient a.getName() et b.getName() ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
private int level = 6;. Son constructeur est public Beacon(int level) { this.level = level + 2; }. Que stocke new Beacon(3) ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
public Tag(String text). Quel constructeur supplémentaire fournit une surcharge distincte ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
scale(k) multiplie les deux dimensions par k ; area() renvoie leur produit. Exécute scale(2); double saved = area(); scale(0.5);. Que valent saved et le résultat final de area() ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Dial nouvellement utilisée possède un champ d’instance value et un champ statique created, tous deux initialement à 0. Chaque constructeur incrémente created une fois ; turn() n’incrémente que la valeur de son objet receveur. Exécute Dial a = new Dial(); Dial b = a; b.turn(); b = new Dial(); b.turn(); b.turn();. Que valent a.value, b.value et created ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
private String label;. Quelle implémentation fournit cette valeur à son appelant ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
setLevel. Le constructeur appelle ce mutateur et raise() appelle setLevel(this.level + 1). En partant de new Level(13), exécute raise(); setLevel(-2); raise(); raise();. Quel est le niveau final ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
String.format(java.util.Locale.US, "%02d:%02d", 4, 7) renvoie-t-elle ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Seat doit refuser une deuxième réservation tant que la première n’est pas annulée. Un test ne vérifie actuellement que le premier appel réussi à reserve(). Quel appel suivant vérifie le mieux la règle de refus ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 4 : Diagnostique les conceptions et combine les règles10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Pump devrait-elle représenter cela ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Token possède une valeur numérique et addOne() l’augmente. Exécute Token a = new Token(2); Token b = a; b.addOne(); Token c = new Token(7); a = c; a.addOne(); b.addOne();. Quelles valeurs a, b et c indiquent-ils ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
add(int amount) déclare actuellement int total = amount; dans son corps. Quelle modification du stockage rend l’accumulation possible ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
Une classe Bucket déclare private int capacity = 2; et une liste d’instance vide items. Son constructeur est Bucket(int capacity) { capacity = capacity; }. add renvoie false sans ajouter d’élément lorsque la taille de la liste est au moins égale à la capacité stockée ; sinon, elle ajoute l’élément et renvoie true. snapshot() renvoie new ArrayList<>(this.items).
Exécute Bucket b = new Bucket(4); b.add("A"); ArrayList<String> view = b.snapshot(); view.add("B");. Appelle ensuite b.add("C") et b.add("D"). Que renvoient ces deux derniers appels et combien d’éléments b contient-il finalement ?
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Route possède un champ final code et un champ statique created, initialement à 0. Ses constructeurs sont Route() { this("local"); created++; } et Route(String code) { this.code = code; created++; }. Après un appel à chaque constructeur, created devrait compter deux objets. Quelle correction donne le bon compte ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
advance() ajoute une minute et revient au début du cycle de 24 heures. getHour() lit l’heure courante. Exécute int h = getHour(); advance(); if (getHour() != h) { advance(); } advance();. Que valent h et l’heure finale ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
scale. Son accesseur renvoie this.width * this.height et il n’existe aucun champ d’aire. Pourquoi cette conception de l’accesseur est-elle valide ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Album est limité à trois légendes. Son constructeur rejette plus de trois légendes et stocke new ArrayList<>(captions). getCaptions() renvoie une autre copie ; addCaption refuse les ajouts lorsque la limite est atteinte. Un appelant fournit deux légendes, en ajoute une troisième à la liste originale, ajoute une légende au résultat d’un accesseur, puis appelle une fois addCaption. Combien de légendes l’Album contient-il ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Door doit refuser open() lorsqu’elle est verrouillée. Une porte nouvellement créée est fermée et déverrouillée. lock() ne réussit que si la porte est fermée ; unlock() la déverrouille. Quelle séquence de test vérifie le refus lorsque la porte est verrouillée, puis une ouverture réussie après son déverrouillage ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Tu bloques sur ton propre exercice ? Aide aux Devoirs
Mots-Clés
A
Accès de paquetage
int count; permet à une autre classe du même paquetage sans nom de lire ou de modifier le champ.Accesseur
get.getArea() peut calculer la largeur multipliée par la hauteur même lorsque la classe ne stocke aucun champ d’aire distinct.Appel récursif de constructeur
Box() et Box(int) délèguent l’un à l’autre.Argument
new Clock(9, 5), les arguments 9 et 5 fournissent l’heure et la minute de la nouvelle horloge.C
Chaînage de constructeurs
this(...).this(name, species, 0) pour réutiliser l’initialisation avec un âge par défaut.Champ final
Champ statique
created peut augmenter chaque fois que le constructeur initialise une nouvelle instance de la classe.Classe
Pet rassemble un nom, une espèce et un âge avec des opérations comme celebrateBirthday().Comportement
lend() et giveBack() pour que les appelants puissent gérer son état de prêt.Conception de classe
Constante
static final, souvent public et nommé en UPPER_SNAKE_CASE.MAX_CELSIUS fournit la même limite supérieure de température à la classe et à ses appelants.Constructeur
Pet copie le nom, l’espèce et l’âge fournis dans les champs du nouvel animal.Constructeur par défaut
new Pet() nécessite donc une surcharge explicite.Constructeur sans argument
Clock() peut déléguer avec this(0, 0) pour démarrer l’horloge à minuit.Contexte statique
pet.getAge() fournit au contraire un objet précis.Copie défensive
new ArrayList<>(this.tracks) empêche les modifications extérieures de la liste d’atteindre la liste interne.D
Développement incrémental
Durée de vie
É
Écrêtage
État
E
Encapsulation
Pet associe un champ d’âge privé à des méthodes de vérification qui refusent les modifications invalides.I
IllegalArgumentException
IllegalArgumentException est une exception qu’une méthode ou un constructeur peut lever pour rejeter un argument qui ne respecte pas ses règles d’entrée.IllegalArgumentException pour une capacité négative empêche la construction de renvoyer un objet invalide.Initialisation
new ArrayList<>() pour permettre l’ajout ultérieur d’éléments.Instance
Pet lorsque chacun est créé séparément.Interface publique
lend(), giveBack() et isLentOut() tandis que son indicateur de prêt reste privé.Invariant
M
Masquage
this.age = age; utile : le côté gauche désigne le champ et le côté droit la valeur fournie.Masquage de l’information
getHours() cohérente pour les appelants existants.Méthode d’action
lend() vérifie l’état actuel du prêt, refuse un nouveau prêt et indique si le prêt a réussi.Méthode d’instance
scale est une méthode d’instance : a.scale(2) modifie le rectangle a tandis qu’un rectangle distinct reste inchangé.Méthode statique
main peut créer Counter c, puis appeler c.increment() par cette référence.Modificateur d’accès
private, protected ou public qui contrôle l’accès à une déclaration.private rend une méthode auxiliaire disponible dans sa classe sans l’exposer aux autres classes.Mutateur
setAge(int age) peut ignorer les entrées négatives afin que l’âge stocké reste dans son intervalle autorisé.N
new
new commence une expression de création d’objet qui exécute un constructeur et produit une référence vers l’objet.new Pet("Luna", "cat", 3) crée un animal et fournit trois arguments pour son état initial.Notation pointée
luna.getAge() indique à Java que l’animal désigné par luna doit fournir son âge.null
null signifie qu’une référence ne donne accès à aucun objet ; les champs dont le type est une classe la reçoivent sauf s’ils sont initialisés autrement.add sur un champ de type liste qui vaut encore null échoue, car aucun objet liste n’a été créé.O
Objet
new distinctes, peuvent avoir des âges différents tout en suivant une même définition de classe.Objet receveur
book.lend(), l’objet receveur est le livre désigné par book, dont la méthode vérifie l’indicateur de prêt.P
Paramètre
age d’un constructeur d’animal reçoit 3 lorsque l’appel fournit 3 à cette place.Portée
if s’arrête à ce bloc : le code suivant ne peut donc pas utiliser son nom.private
private limite l’accès à un membre au code situé dans sa classe, obligeant les appelants de classes de premier niveau distinctes à passer par l’interface publique.pet.age = -1; dans une classe Main distincte et nécessite un appel de méthode contrôlé.Propriété en lecture seule
getTitle() mais d’aucune opération pour remplacer le titre.protected
protected autorise l’accès depuis le même paquetage et un accès restreint depuis le code des sous-classes extérieures à ce paquetage.public
public autorise l’accès à un membre partout où le type qui le déclare est accessible, afin que les appelants puissent utiliser l’opération exposée.lend() publique permet à Main de demander un prêt tandis que le champ privé d’état du livre reste masqué.R
Référence
Pet other = luna;, les deux variables contiennent des références vers le même animal, et chacune peut donc y accéder.Résultat attendu
lend() sur un livre emprunté est false, avec un indicateur de prêt inchangé.S
String.format
String.format construit du texte à partir d’une chaîne de format et de valeurs, en prenant notamment en charge des largeurs fixes et des décimales.String.format avec java.util.Locale.US et "%.2f" formate 7,5 sous la forme "7.50" quels que soient les paramètres régionaux par défaut.Surcharge de constructeurs
T
Test aux limites
this
this désigne l’objet courant dans le code d’instance et distingue ses champs des paramètres de même nom.this.name = name; écrit la nouvelle valeur fournie dans le champ de cet animal précis.toString
toString() renvoie la représentation textuelle d’un objet, ce qui permet à l’affichage et à la concaténation de chaînes de montrer des détails lisibles.toString d’une horloge renvoie "09:05", donc afficher l’horloge montre une heure utile au lieu d’un texte contenant la classe et le code de hachage.Trace des états
V
Valeur de retour
r.area() peut être doublée dans une expression ; afficher l’aire seule ne fournit aucune valeur.Valeur par défaut
false ; une variable booléenne locale doit recevoir une valeur avant de pouvoir être lue.Validation
Variable d’instance
age de chaque animal conserve sa propre valeur, même si la déclaration n’apparaît qu’une fois dans Pet.Variable locale
total dans une méthode de calcul contient une valeur temporaire que l’objet n’a pas besoin de mémoriser.void
void indique qu’une méthode ne fournit aucune valeur de retour, même lorsqu’elle modifie l’état ou affiche une sortie.void, car son rôle est d’augmenter l’âge stocké de son objet receveur.#
@Override
@Override demande au compilateur de vérifier qu’une déclaration de méthode remplace une méthode déjà fournie par un supertype.@Override placé au-dessus de tostring() révèle son erreur de majuscule au lieu de laisser l’affichage automatique inchangé.- 1Premiers programmes Java
- 2Conditions et boucles en Java
- 3Méthodes Java
- 4Listes et tableaux en Java
- 5Classes et objets en Java
- 6Références et égalité en Java
- 7HashMap et collections en Java
- 8Héritage et polymorphisme en Java
- 9Exceptions et fichiers en Java
- 10Paquetages et tests unitaires Java
- 11Généricité et flux en Java
À propos de cette unité
Crée ton propre Matériel d'Étude
Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.