Cara menyimpan data dalam objek Java

Terakhir dikemas kini: Januari 2020

Walaupun butang tunda mungkin merupakan butang yang paling biasa digunakan pada jam penggera, malah AlarmClockkelas sederhana memerlukan beberapa lagi ciri. Sebagai contoh, anda mungkin ingin mengawal berapa lama jam penggera akan kekal dalam mod tunda. Untuk menambahkan ciri seperti itu, anda perlu memahami bagaimana Java mengendalikan data.

Pembangun menggunakan pemboleh ubah di Java untuk menyimpan data, dengan semua pemboleh ubah mempunyai jenis data dan nama. Jenis data menentukan nilai yang boleh dimiliki oleh pemboleh ubah. Dalam tutorial ini, anda akan belajar bagaimana jenis integral memegang nombor bulat, jenis titik terapung memegang nombor nyata, dan jenis rentetan memegang rentetan watak. Kemudian anda akan mula menggunakan pemboleh ubah contoh di kelas Java anda.

Pemboleh ubah dan jenis primitif

Jenis primitif yang disebut , jenis integral dan floating point adalah jenis data termudah di Java. Program berikut menggambarkan jenis kamiran, yang dapat menyimpan nombor bulat positif dan negatif. Program ini juga menggambarkan komen, yang mendokumentasikan kod anda tetapi tidak mempengaruhi program dengan cara apa pun.

/ * * Ini juga komen. Penyusun mengabaikan segalanya dari * yang pertama / * sehingga "bintang slash" yang mengakhiri komen. * * Inilah "garis miring bintang" yang mengakhiri komen. * / kelas awam IntegerTest {public static void main (String [] args) {// Berikut adalah pengisytiharan pemboleh ubah int yang dipanggil anInteger, // yang anda berikan nilai awalnya 100. int anInteger = 100; // Menyatakan dan memulakan InInteger System.out.println (anInteger); // Output 100 // Anda juga boleh melakukan aritmetik dengan jenis primitif, menggunakan // operator aritmetik standard. anInteger = 100 + 100; System.out.println (anInteger); // Keluaran 200}}

Java juga menggunakan jenis titik terapung, yang dapat menyimpan angka nyata, yang bermaksud angka yang merangkumi tempat perpuluhan. Berikut adalah contoh program:

kelas awam DoubleTest {public static void main (String [] args) {// Berikut adalah pengisytiharan pemboleh ubah berganda yang disebut aDouble. // Anda juga memberikan nilai awal aDouble sebanyak 5.76. double aDouble = 5.76; // Menyatakan dan memulakan aDouble System.out.println (aDouble); // Output 5.76 // Anda juga boleh melakukan aritmetik dengan jenis titik terapung. aDouble = 5.76 + 1.45; System.out.println (aDouble); // Keluaran 7.21}}

Cuba jalankan program di atas. Ingat, anda mesti menyusunnya sebelum dapat menjalankannya:

javac * .java java IntegerTest java DoubleTest 

Java menggunakan empat jenis integral dan dua jenis titik terapung, yang keduanya memiliki rentang angka yang berlainan dan mengambil ruang penyimpanan yang berbeza-beza, seperti yang ditunjukkan dalam jadual di bawah.

Jenis integral

JENIS Bait Pendek Int Lama
SAIZ (bit) 8 16 32 64
PERINGKAT -128 hingga 127 -32,768 hingga 32,767 -2,147,483,648 hingga 2,147,483,647 -263 hingga 263-1

Jenis titik terapung (format IEEE 754)

 
JENIS Titik terapung berketepatan tunggal Titik terapung berketepatan ganda
SAIZ (bit) 32 64
PERINGKAT +/- 1.18x10-38 hingga +/- 3.4x1038 +/- 2.23x10-308 hingga +/- 1.8x10308

A jenis tali memegang tali, dan mengendalikan mereka berbeza dari jalan penting dan jenis titik terapung mengendalikan nombor. Bahasa Java merangkumi Stringkelas untuk mewakili rentetan. Anda menyatakan rentetan menggunakan jenis String, dan menginisialisasi dengan rentetan yang dikutip, urutan watak yang terdapat dalam petikan ganda, seperti yang ditunjukkan di bawah. Anda juga boleh menggabungkan dua tali menggunakan +operator.

// Fragmen kod // Perisytiharan variabel s dari jenis String, // dan inisialisasi dengan petikan petikan "Hello." Rentetan s = "Hello"; // Gabungan rentetan dalam s dengan rentetan petikan "World" String t = s + "World"; System.out.println (t); // Keluaran Hello World

Skop boleh ubah

Selain jenis, ruang lingkup juga merupakan ciri penting pemboleh ubah. Skop menentukan bila pemboleh ubah dibuat dan dimusnahkan dan di mana pembangun boleh mengakses pemboleh ubah dalam program. Tempat dalam program anda di mana anda menyatakan pemboleh ubah menentukan skopnya.

Sejauh ini, saya telah membincangkan pemboleh ubah tempatan , yang menyimpan data sementara yang anda gunakan dalam satu kaedah. Anda menyatakan pemboleh ubah tempatan di dalam kaedah, dan anda boleh mengaksesnya hanya dari kaedah tersebut. Ini bermaksud bahawa anda hanya boleh mendapatkan pemboleh ubah tempatan anInteger, yang anda gunakan IntegerTest, dan aDouble, yang anda gunakan DoubleTest, dari kaedah utama di mana ia diisytiharkan dan tidak di tempat lain.

Anda boleh menyatakan pemboleh ubah tempatan dalam kaedah apa pun. Contoh kod di bawah menyatakan pemboleh ubah tempatan dalam AlarmClock snooze()kaedah:

kelas awam AlarmClock {public void snooze () {// Waktu tunda dalam milisaat = 5 saat tunda lamaInterval = 5000; System.out.println ("ZZZZZ untuk:" + snoozeInterval); }}

Anda boleh mendapatkan snoozeIntervalhanya dari snooze()kaedah, di mana anda menyatakansnoozeInterval, as shown here: 

kelas awam AlarmClockTest {public static void main (String [] args) {AlarmClock aClock = baru AlarmClock (); aClock.snooze (); // Ini masih baik. // Baris kod seterusnya adalah RALAT . // Anda tidak dapat mengakses snoozeInterval di luar kaedah tunda. snoozeInterval = 10000; }}

Parameter kaedah

A Cara parameter , yang mempunyai skop yang sama dengan pembolehubah tempatan, adalah satu lagi jenis berubah-ubah. Parameter kaedah menyampaikan argumen menjadi kaedah. Apabila anda menyatakan kaedah, anda menentukan argumennya dalam senarai parameter. Anda menyampaikan hujah semasa anda memanggil kaedah. Parameter kaedah berfungsi sama dengan pemboleh ubah tempatan kerana ia berada dalam ruang lingkup kaedah yang dihubungkan, dan dapat digunakan sepanjang metode. Namun, tidak seperti pemboleh ubah tempatan, parameter kaedah memperoleh nilai dari pemanggil ketika memanggil kaedah. Berikut adalah pengubahsuaian jam penggera yang membolehkan anda melewati snoozeInterval.

kelas awam 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(); // Pass in the snooze interval when you call the method. aClock.snooze(10000); // Snooze for 10000 msecs. } } 

Member variables: How objects store data

Local variables are useful, but because they provide only temporary storage, their value is limited. Since their lifetimes span the length of the method in which they are declared, local variables compare to a notepad that appears every time you receive a telephone call, but disappears when you hang up. That setup can be useful for jotting down notes, but sometimes you need something more permanent. What's a programmer to do? Enter member variables.

Member variables -- of which there are two, instance and static -- make up part of a class.

Variable scope and lifetime

Developers implement instance variables to contain data useful to a class. An instance variable differs from a local variable in the nature of its scope and its lifetime. The entire class makes up the scope of an instance variable, not the method in which it was declared. In other words, developers can access instance variables anywhere in the class. In addition, the lifetime of an instance variable does not depend on any particular method of the class; that is, its lifetime is the lifetime of the instance that contains it.

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

Cubalah program ini, dan anda akan melihat bahawa aClock1masih mempunyai selang 5,000 dan aClock2selang 10,000. Sekali lagi, setiap contoh mempunyai data contohnya sendiri.

Jangan lupa, definisi kelas hanya cetak biru, jadi pemboleh ubah contoh sebenarnya tidak wujud sehingga anda membuat contoh dari cetak biru. Setiap contoh kelas mempunyai salinan pemboleh ubah instance sendiri, dan cetak biru menentukan apakah pemboleh ubah contoh itu.

JavaWorld

Enkapsulasi

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

Walaupun program sederhana itu menunjukkan bagaimana anda dapat menghadapi masalah jika anda mengakses data dalaman kelas secara langsung. Semakin besar dan kompleks program ini, semakin penting enkapsulasi. Ingat juga bahawa banyak program bermula kecil dan kemudian berkembang sehingga kekal, jadi sangat penting untuk anda merancangnya dengan betul, sejak awal. Untuk menerapkan enkapsulasi AlarmClock, anda hanya boleh membuat kaedah untuk memanipulasi selang tunda.

Catatan mengenai kaedah

Kaedah boleh mengembalikan nilai yang digunakan pemanggil. Untuk mengembalikan nilai, nyatakan jenis pengembalian bukan kekosongan, dan gunakan returnpernyataan. The getSnoozeInterval()kaedah yang ditunjukkan dalam contoh di bawah menggambarkan ini.

Tulis program