Comment stocker des données dans des objets Java

Dernière mise à jour: janvier 2020

Bien que le bouton snooze soit probablement le bouton le plus couramment utilisé sur un réveil, même une AlarmClockclasse simple a besoin de quelques fonctionnalités supplémentaires. Par exemple, vous souhaiterez peut-être contrôler la durée pendant laquelle le réveil restera en mode répétition. Pour ajouter une telle fonctionnalité, vous devez comprendre comment Java contrôle les données.

Les développeurs utilisent des variables en Java pour contenir des données, toutes les variables ayant un type de données et un nom. Le type de données détermine les valeurs qu'une variable peut contenir. Dans ce didacticiel, vous apprendrez comment les types intégraux contiennent des nombres entiers, les types à virgule flottante contiennent des nombres réels et les types chaîne contiennent des chaînes de caractères. Ensuite, vous commencerez à utiliser des variables d'instance dans vos classes Java.

Variables et types primitifs

Les types primitifs appelés, les types intégraux et à virgule flottante sont les types de données les plus simples en Java. Le programme suivant illustre le type intégral, qui peut contenir des nombres entiers positifs et négatifs. Ce programme illustre également les commentaires, qui documentent votre code mais n'affectent en aucune façon le programme.

/ * * Ceci est également un commentaire. Le compilateur ignore tout depuis * le premier / * jusqu'à une "barre oblique" qui termine le commentaire. * * Voici la "barre oblique" qui termine le commentaire. * / public class IntegerTest {public static void main (String [] args) {// Voici la déclaration d'une variable int appelée anInteger, // à laquelle vous donnez une valeur initiale de 100. int anInteger = 100; // Déclare et initialise anInteger System.out.println (anInteger); // Sorties 100 // Vous pouvez également faire de l'arithmétique avec des types primitifs, en utilisant les // opérateurs arithmétiques standard. anInteger = 100 + 100; System.out.println (anInteger); // Sorties 200}}

Java utilise également des types à virgule flottante, qui peuvent contenir des nombres réels, c'est-à-dire des nombres comprenant une décimale. Voici un exemple de programme:

public class DoubleTest {public static void main (String [] args) {// Voici la déclaration d'une variable double appelée aDouble. // Vous donnez également à aDouble une valeur initiale de 5,76. double aDouble = 5,76; // Déclare et initialise aDouble System.out.println (aDouble); // Sorties 5.76 // Vous pouvez également faire de l'arithmétique avec des types à virgule flottante. aDouble = 5,76 + 1,45; System.out.println (aDouble); // Sorties 7.21}}

Essayez d'exécuter les programmes ci-dessus. N'oubliez pas que vous devez compiler avant de pouvoir les exécuter:

javac * .java java IntegerTest java DoubleTest 

Java utilise quatre types intégraux et deux types à virgule flottante, qui contiennent tous deux des plages de nombres différentes et occupent des quantités variables d'espace de stockage, comme indiqué dans les tableaux ci-dessous.

Types intégraux

TYPE Octet Court Int Longue
TAILLE (bits) 8 16 32 64
INTERVALLE -128 à 127 -32 768 à 32 767 -2 147 483 648 à 2 147 483 647 -263 à 263-1

Types à virgule flottante (format IEEE 754)

 
TYPE Virgule flottante simple précision Virgule flottante double précision
TAILLE (bits) 32 64
INTERVALLE +/- 1,18x10-38 à +/- 3,4x1038 +/- 2,23x10-308 à +/- 1,8x10308

Un type chaîne contient des chaînes et les gère différemment de la façon dont les types à virgule flottante et intégrale gèrent les nombres. Le langage Java comprend une Stringclasse pour représenter les chaînes. Vous déclarez une chaîne à l'aide du type Stringet l'initialisez avec une chaîne entre guillemets, une séquence de caractères entre guillemets, comme indiqué ci-dessous. Vous pouvez également combiner deux chaînes à l'aide de l' +opérateur.

// Fragment de code // Déclaration de la variable s de type String, // et initialisation avec la chaîne entre guillemets "Hello". String s = "Bonjour"; // Concaténation de la chaîne en s avec la chaîne entre guillemets "World" String t = s + "World"; System.out.println (t); // Sorties Hello World

Portée variable

Outre le type, la portée est également une caractéristique importante d'une variable. Scope établit quand une variable est créée et détruite et où un développeur peut accéder à la variable dans un programme. L'endroit dans votre programme où vous déclarez la variable détermine sa portée.

Jusqu'à présent, j'ai discuté des variables locales , qui contiennent des données temporaires que vous utilisez dans une méthode. Vous déclarez des variables locales dans des méthodes et vous ne pouvez y accéder qu'à partir de ces méthodes. Cela signifie que vous ne pouvez récupérer que les variables locales anInteger, que vous avez utilisées dans IntegerTestet aDoubleque vous avez utilisées dans DoubleTest, à partir de la méthode principale dans laquelle elles ont été déclarées et nulle part ailleurs.

Vous pouvez déclarer des variables locales dans n'importe quelle méthode. L'exemple de code ci-dessous déclare une variable locale dans la AlarmClock snooze()méthode:

public class AlarmClock {public void snooze () {// Temps de répétition en millisecondes = 5 secondes long snoozeInterval = 5000; System.out.println ("ZZZZZ pour:" + snoozeInterval); }}

Vous pouvez accéder snoozeIntervaluniquement à partir de la snooze()méthode, qui est l'endroit où vous avez déclarésnoozeInterval, as shown here: 

public class AlarmClockTest {public static void main (String [] args) {AlarmClock aClock = new AlarmClock (); aClock.snooze (); // C'est toujours bien. // La ligne de code suivante est une ERREUR . // Vous ne pouvez pas accéder à snoozeInterval en dehors de la méthode snooze. snoozeInterval = 10000; }}

Paramètres de méthode

Un paramètre de méthode , qui a une portée similaire à une variable locale, est un autre type de variable. Les paramètres de méthode transmettent des arguments aux méthodes. Lorsque vous déclarez la méthode, vous spécifiez ses arguments dans une liste de paramètres. Vous passez les arguments lorsque vous appelez la méthode. Les paramètres de méthode fonctionnent de la même manière que les variables locales en ce sens qu'ils s'inscrivent dans le champ d'application de la méthode à laquelle ils sont liés et peuvent être utilisés dans toute la méthode. Cependant, contrairement aux variables locales, les paramètres de méthode obtiennent une valeur de l'appelant lorsqu'il appelle une méthode. Voici une modification du réveil qui vous permet de passer dans le snoozeInterval.

public class AlarmClock {public void snooze (long snoozeInterval) {System.out.println ("ZZZZZ for:" + snoozeInterval); }}
public class AlarmClockTest {public static void main (String [] args) {AlarmClock aClock = new AlarmClock (); // Passez l'intervalle de répétition lorsque vous appelez la méthode. aClock.snooze (10000); // Répéter pendant 10000 ms. }}

Variables membres: comment les objets stockent les données

Les variables locales sont utiles, mais comme elles ne fournissent qu'un stockage temporaire, leur valeur est limitée. Étant donné que leur durée de vie s'étend sur la durée de la méthode dans laquelle elles sont déclarées, les variables locales se comparent à un bloc-notes qui apparaît chaque fois que vous recevez un appel téléphonique, mais disparaît lorsque vous raccrochez. Cette configuration peut être utile pour prendre des notes, mais parfois vous avez besoin de quelque chose de plus permanent. Que doit faire un programmeur? Entrez les variables de membre .

Les variables membres - dont il y en a deux, instance et static - font partie d'une classe.

Portée et durée de vie variables

Les développeurs implémentent des variables d'instance pour contenir des données utiles à une classe. Une variable d'instance diffère d'une variable locale par la nature de sa portée et sa durée de vie. La classe entière constitue la portée d'une variable d'instance, pas la méthode dans laquelle elle a été déclarée. En d'autres termes, les développeurs peuvent accéder aux variables d'instance n'importe où dans la classe. De plus, la durée de vie d'une variable d'instance ne dépend d'aucune méthode particulière de la classe; autrement dit, sa durée de vie est la durée de vie de l'instance qui la contient.

Instances are the actual objects that you create from the blueprint you design in the class definition. You declare instance variables in the class definition, affecting each instance you create from the blueprint. Each instance contains those instance variables, and data held within the variables can vary from instance to instance.

Consider the AlarmClock class. Passing the snoozeInterval into the snooze() method isn't a great design. Imagine having to type in a snooze interval on your alarm clock each time you fumbled for the snooze button. Instead, just give the whole alarm clock a snoozeInterval. You complete this with an instance variable in the AlarmClock class, as shown below:

public class AlarmClock { // You declare snoozeInterval here. This makes it an instance variable. // You also initialize it here. long m_snoozeInterval = 5000; // Snooze time in millisecond = 5 secs. public void snooze() { // You can still get to m_snoozeInterval in an AlarmClock method // because you are within the scope of the class. System.out.println("ZZZZZ for: " + m_snoozeInterval); } } 

You can access instance variables almost anywhere within the class that declares them. To be technical about it, you declare the instance variable within the class scope, and you can retrieve it from almost anywhere within that scope. Practically speaking, you can access the variable anywhere between the first curly bracket that starts the class and the closing bracket. Since you also declare methods within the class scope, they too can access the instance variables.

You can also access instance variables from outside the class, as long as an instance exists, and you have a variable that references the instance. To retrieve an instance variable through an instance, you use the dot operator together with the instance. That may not be the ideal way to access the variable, but for now, complete it this way for illustrative purposes:

public class AlarmClockTest { public static void main(String[] args) { // Create two clocks. Each has its own m_snoozeInterval AlarmClock aClock1 = new AlarmClock(); AlarmClock aClock2 = new AlarmClock(); // Change aClock2 // You'll soon see that there are much better ways to do this. aClock2.m_snoozeInterval = 10000; aClock1.snooze(); // Snooze with aClock1's interval aClock2.snooze(); // Snooze with aClock2's interval } } 

Essayez ce programme, et vous verrez qu'il a aClock1toujours son intervalle de 5 000 alors qu'il aClock2a un intervalle de 10 000. Encore une fois, chaque instance a ses propres données d'instance.

N'oubliez pas que la définition de classe n'est qu'un modèle, de sorte que les variables d'instance n'existent pas réellement tant que vous n'avez pas créé des instances à partir du modèle. Chaque instance d'une classe a sa propre copie des variables d'instance et le plan définit ce que seront ces variables d'instance.

JavaWorld

Encapsulation

Encapsulation is one of the foundations of object-oriented programming. When using encapsulation, the user interacts with the type through the exposed behavior, not directly with the internal implementation. Through encapsulation, you hide the details of a type's implementation. In Java, encapsulation basically translates to this simple guideline: "Don't access your object's data directly; use its methods."

That is an elementary idea, but it eases our lives as programmers. Imagine, for example, that you wanted to instruct a Person object to stand up. Without encapsulation, your commands could go something like this: "Well, I guess you'd need to tighten this muscle here at the front of the leg, loosen this muscle here at the back of the leg. Hmmm -- need to bend at the waist too. Which muscles spark that movement? Need to tighten these, loosen those. Whoops! Forgot the other leg. Darn. Watch it -- don't tip over ..." You get the idea. With encapsulation, you would just need to invoke the standUp() method. Pretty easy, yes?

Some advantages to encapsulation:

  • Abstraction of detail: The user interacts with a type at a higher level. If you use the standUp() method, you no longer need to know all the muscles required to initiate that motion.
  • Isolation from changes: Changes in internal implementation don't affect the users. If a person sprains an ankle, and depends on a cane for a while, the users still invoke only the standUp() method.
  • Correctness: Users can't arbitrarily change the insides of an object. They can only complete what you allow them to do in the methods you write.

Here's a short example in which encapsulation clearly helps in a program's accuracy:

// Bad -- doesn't use encapsulation public class Person { int m_age; } public class PersonTest { public static void main(String[] args) { Person p = new Person(); p.m_age = -5; // Hey -- how can someone be minus 5 years old? } } // Better - uses encapsulation public class Person { int m_age; public void setAge(int age) { // Check to make sure age is greater than 0. I'll talk more about // if statements at another time. if (age > 0) { m_age = age; } } } public class PersonTest { public static void main(String[] args) { Person p = new Person(); p.setAge(-5); // Won't have any effect now. } } 

Même ce simple programme montre comment vous pouvez vous retrouver en difficulté si vous accédez directement aux données internes des classes. Plus le programme est volumineux et complexe, plus l'encapsulation devient importante. N'oubliez pas que de nombreux programmes commencent petit et durent indéfiniment, il est donc essentiel de les concevoir correctement, dès le début. Pour appliquer l'encapsulation à AlarmClock, vous pouvez simplement créer des méthodes pour manipuler l'intervalle de répétition.

Une note sur les méthodes

Les méthodes peuvent renvoyer des valeurs utilisées par l'appelant. Pour renvoyer une valeur, déclarez un type de retour nonvoid et utilisez une returninstruction. La getSnoozeInterval()méthode illustrée dans l'exemple ci-dessous illustre cela.

Ecrire le programme