Come memorizzare i dati negli oggetti Java

Ultimo aggiornamento: gennaio 2020

Sebbene il pulsante snooze sia probabilmente il pulsante più comunemente usato su una sveglia, anche una AlarmClocklezione semplice necessita di alcune funzionalità in più. Ad esempio, potresti voler controllare per quanto tempo la sveglia rimarrà in modalità snooze. Per aggiungere una tale funzionalità, è necessario comprendere in che modo Java controlla i dati.

Gli sviluppatori utilizzano le variabili in Java per contenere i dati, con tutte le variabili che hanno un tipo di dati e un nome. Il tipo di dati determina i valori che una variabile può contenere. In questo tutorial imparerai come i tipi integrali contengono numeri interi, i tipi in virgola mobile contengono numeri reali e i tipi stringa contengono stringhe di caratteri. Quindi inizierai a utilizzare le variabili di istanza nelle tue classi Java.

Variabili e tipi primitivi

I tipi primitivi chiamati, i tipi integrali e in virgola mobile sono i tipi di dati più semplici in Java. Il seguente programma illustra il tipo integrale, che può contenere numeri interi positivi e negativi. Questo programma illustra anche i commenti, che documentano il codice ma non influiscono in alcun modo sul programma.

/ * * Anche questo è un commento. Il compilatore ignora tutto da * il primo / * fino a una "barra a stella" che termina il commento. * * Ecco la "barra a stella" che conclude il commento. * / public class IntegerTest {public static void main (String [] args) {// Ecco la dichiarazione di una variabile int chiamata anInteger, // a cui fornisci un valore iniziale di 100. int anInteger = 100; // Dichiara e inizializza un intero System.out.println (anInteger); // Output 100 // È anche possibile eseguire operazioni aritmetiche con tipi primitivi, utilizzando // gli operatori aritmetici standard. un intero = 100 + 100; System.out.println (anInteger); // Output 200}}

Java utilizza anche tipi a virgola mobile, che possono contenere numeri reali, ovvero numeri che includono una posizione decimale. Ecco un programma di esempio:

public class DoubleTest {public static void main (String [] args) {// Ecco la dichiarazione di una doppia variabile chiamata aDouble. // Inoltre dai aDouble un valore iniziale di 5.76. double aDouble = 5.76; // Dichiara e inizializza aDouble System.out.println (aDouble); // Output 5.76 // Puoi anche eseguire operazioni aritmetiche con tipi in virgola mobile. aDoppio = 5,76 + 1,45; System.out.println (aDouble); // Output 7.21}}

Prova a eseguire i programmi sopra. Ricorda, devi compilare prima di poterli eseguire:

javac * .java java IntegerTest java DoubleTest 

Java utilizza quattro tipi integrali e due tipi a virgola mobile, che contengono entrambi intervalli di numeri diversi e occupano quantità variabili di spazio di archiviazione, come mostrato nelle tabelle seguenti.

Tipi integrali

GENERE Byte Corto Int Lungo
DIMENSIONE (bit) 8 16 32 64
GAMMA Da -128 a 127 Da -32.768 a 32.767 -2.147.483.648 a 2.147.483.647 Da -263 a 263-1

Tipi in virgola mobile (formato IEEE 754)

 
GENERE Virgola mobile a precisione singola Virgola mobile a doppia precisione
DIMENSIONE (bit) 32 64
GAMMA Da +/- 1,18x10-38 a +/- 3,4x1038 Da +/- 2,23x10-308 a +/- 1,8x10308

Un tipo stringa contiene le stringhe e le gestisce in modo diverso dal modo in cui i tipi a virgola mobile e integrale gestiscono i numeri. Il linguaggio Java include una Stringclasse per rappresentare le stringhe. Dichiari una stringa utilizzando il tipo Stringe la inizializzi con una stringa tra virgolette, una sequenza di caratteri contenuta tra virgolette, come mostrato di seguito. È inoltre possibile combinare due stringhe utilizzando l' +operatore.

// Frammento di codice // Dichiarazione di variabili s di tipo String, // e inizializzazione con stringa tra virgolette "Hello". String s = "Hello"; // Concatenazione di una stringa in s con una stringa tra virgolette "World" String t = s + "World"; System.out.println (t); // Emette Hello World

Ambito variabile

Oltre al tipo, anche l' ambito è una caratteristica importante di una variabile. L'ambito stabilisce quando una variabile viene creata e distrutta e dove uno sviluppatore può accedere alla variabile all'interno di un programma. La posizione nel programma in cui si dichiara la variabile determina il suo ambito.

Finora, ho discusso delle variabili locali , che contengono dati temporanei che usi all'interno di un metodo. Dichiari variabili locali all'interno dei metodi e puoi accedervi solo dall'interno di quei metodi. Ciò significa che puoi recuperare solo le variabili locali anInteger, che hai usato IntegerTeste aDouble, che hai usato DoubleTest, dal metodo principale in cui sono state dichiarate e da nessun'altra parte.

Puoi dichiarare variabili locali all'interno di qualsiasi metodo. Il codice di esempio seguente dichiara una variabile locale nel AlarmClock snooze()metodo:

public class AlarmClock {public void snooze () {// Snooze time in millisecond = 5 secs long snoozeInterval = 5000; System.out.println ("ZZZZZ for:" + snoozeInterval); }}

Puoi accedere snoozeIntervalsolo dal snooze()metodo, che è dove hai dichiaratosnoozeInterval, as shown here: 

public class AlarmClockTest {public static void main (String [] args) {AlarmClock aClock = new AlarmClock (); aClock.snooze (); // Va ancora bene. // La riga di codice successiva è un ERRORE . // Non puoi accedere a snoozeInterval al di fuori del metodo snooze. snoozeInterval = 10000; }}

Parametri del metodo

Un parametro del metodo , che ha un ambito simile a una variabile locale, è un altro tipo di variabile. I parametri del metodo passano gli argomenti nei metodi. Quando si dichiara il metodo, si specificano i suoi argomenti in un elenco di parametri. Passi gli argomenti quando chiami il metodo. I parametri del metodo funzionano in modo simile alle variabili locali in quanto rientrano nell'ambito del metodo a cui sono collegati e possono essere utilizzati in tutto il metodo. Tuttavia, a differenza delle variabili locali, i parametri del metodo ottengono un valore dal chiamante quando chiama un metodo. Ecco una modifica della sveglia che ti permette di passare in 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 (); // Passa l'intervallo di snooze quando chiami il metodo. aClock.snooze (10000); // Snooze di 10000 msec. }}

Variabili membro: modalità di archiviazione dei dati da parte degli oggetti

Le variabili locali sono utili, ma poiché forniscono solo memoria temporanea, il loro valore è limitato. Poiché la loro durata è pari alla lunghezza del metodo in cui vengono dichiarate, le variabili locali sono paragonabili a un blocco note che appare ogni volta che si riceve una telefonata, ma scompare quando si riaggancia. Questa configurazione può essere utile per prendere appunti, ma a volte è necessario qualcosa di più permanente. Cosa deve fare un programmatore? Immettere le variabili membro .

Le variabili membro, di cui ce ne sono due, istanza e statica , fanno parte di una classe.

Ambito e durata variabili

Gli sviluppatori implementano variabili di istanza per contenere dati utili a una classe. Una variabile di istanza differisce da una variabile locale per la natura del suo ambito e della sua durata. L'intera classe costituisce l'ambito di una variabile di istanza, non il metodo in cui è stata dichiarata. In altre parole, gli sviluppatori possono accedere alle variabili di istanza ovunque nella classe. Inoltre, la durata di una variabile di istanza non dipende da alcun metodo particolare della classe; ovvero, la sua durata è la durata dell'istanza che lo contiene.

Le istanze sono gli oggetti effettivi che crei dal progetto che progetti nella definizione della classe. Dichiari le variabili di istanza nella definizione della classe, influenzando ogni istanza che crei dal progetto. Ogni istanza contiene tali variabili di istanza e i dati contenuti nelle variabili possono variare da istanza a istanza.

Considera la AlarmClockclasse. Passando il snoozeIntervalnel snooze()metodo non è un grande disegno. Immagina di dover digitare un intervallo di ripetizione sulla sveglia ogni volta che cerchi il pulsante di ripetizione. Invece, dai a tutta la sveglia un snoozeInterval. Completalo con una variabile di istanza nella AlarmClockclasse, come mostrato di seguito:

public class AlarmClock {// Dichiari snoozeInterval qui. Questo lo rende una variabile di istanza. // Lo si inizializza anche qui. long m_snoozeInterval = 5000; // Snooze time in millisecond = 5 secs. public void snooze () {// Puoi ancora arrivare a m_snoozeInterval in un metodo AlarmClock // perché sei nell'ambito della classe. System.out.println ("ZZZZZ per:" + m_snoozeInterval); }}

È possibile accedere alle variabili di istanza quasi ovunque all'interno della classe che le dichiara. Per essere tecnici al riguardo, dichiari la variabile di istanza all'interno dell'ambito della classe e puoi recuperarla da quasi ovunque all'interno di tale ambito. In pratica, puoi accedere alla variabile ovunque tra la prima parentesi graffa che inizia la classe e la parentesi di chiusura. Poiché si dichiarano anche metodi nell'ambito della classe, anch'essi possono accedere alle variabili di istanza.

Puoi anche accedere alle variabili di istanza dall'esterno della classe, purché esista un'istanza e disponi di una variabile che fa riferimento all'istanza. Per recuperare una variabile di istanza tramite un'istanza, si utilizza l' operatore punto insieme all'istanza. Potrebbe non essere il modo ideale per accedere alla variabile, ma per ora completalo in questo modo a scopo illustrativo:

public class AlarmClockTest {public static void main (String [] args) {// Crea due orologi. Ognuno ha il proprio m_snoozeInterval AlarmClock aClock1 = new AlarmClock (); AlarmClock aClock2 = nuovo AlarmClock (); // Cambia aClock2 // Vedrai presto che ci sono modi migliori per farlo. aClock2.m_snoozeInterval = 10000; aClock1.snooze (); // Snooze con l'intervallo di aClock1 aClock2.snooze (); // Snooze con l'intervallo di aClock2}}

Prova questo programma e vedrai che aClock1ha ancora il suo intervallo di 5.000 mentre aClock2ha un intervallo di 10.000. Anche in questo caso, ogni istanza ha i propri dati di istanza.

Non dimenticare che la definizione della classe è solo un modello, quindi le variabili di istanza non esistono effettivamente finché non crei istanze dal progetto. Ogni istanza di una classe ha la propria copia delle variabili di istanza e il progetto definisce quali saranno quelle variabili di istanza.

JavaWorld

Incapsulamento

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. } } 

Anche quel semplice programma mostra come ci si possa cacciare nei guai se si accede direttamente ai dati interni delle classi. Più grande e complesso è il programma, più importante diventa l'incapsulamento. Ricorda anche che molti programmi iniziano in piccolo e poi crescono fino a durare indefinitamente, quindi è essenziale progettarli correttamente, fin dall'inizio. Per applicare l'incapsulamento AlarmClock, puoi semplicemente creare metodi per manipolare l'intervallo di snooze.

Una nota sui metodi

I metodi possono restituire valori utilizzati dal chiamante. Per restituire un valore, dichiarare un tipo restituito nonvoid e utilizzare returnun'istruzione. Il getSnoozeInterval()metodo mostrato nell'esempio seguente lo illustra.

Scrivi il programma