terlindung
Mari kita bicara tentang masalah hak akses yang dilindungi. Lihat Contoh 1 di bawah ini:
Test.java
kelas myObject {} tes kelas publik {public static void main (string [] args) {myObject obj = new myobject (); obj.clone (); // Kompilasi kesalahan. }} Metode klon dari objek tipe tidak terlihat.
Kami telah memahami bahwa objek.clone () adalah metode yang dilindungi. Ini menunjukkan bahwa metode ini dapat diakses oleh subclass dari paket yang sama (java.lang) dan itu (java.lang.object). Berikut adalah kelas myObject (warisan default java.lang.object).
Demikian pula, tes juga merupakan subclass dari java.lang.Object. Namun, metode yang dilindungi dari subclass lain tidak dapat diakses dalam satu subclass, meskipun kedua subclass mewarisi dari kelas induk yang sama.
Mari kita lihat contoh 2 lagi:
Test2.java
kelas myobject2 {clone objek yang dilindungi () melempar clonenotsupportedException {return super.clone (); }} public class test2 {public static void main (string [] args) melempar clonenotsupportedException {myobject2 obj = myobject2 baru (); obj.clone (); // Kompilasi ok. }} Di sini, kami mengganti metode klon () dari kelas induk di kelas MyObject2, memanggil metode klon () di kelas test2 lain, dan kompilasi dan lulus.
Alasan kompilasi jelas. Saat Anda mengganti metode klon () di kelas MyObject2, kelas MyObject2 dan kelas Test2 berada di bawah paket yang sama, sehingga metode yang dilindungi ini terlihat oleh kelas Test2.
Pada titik ini, kita ingat pernyataan dalam Bab 2.2 dalam artikel salinan dangkal dan dalam di Java, ② menimpa metode klon () dari kelas dasar di kelas yang diturunkan dan menyatakannya sebagai publik. Sekarang saya memahami alasan kalimat ini (untuk memungkinkan kelas lain untuk memanggil metode klon () dari kelas ini, setelah kelebihan beban, atribut metode klon () harus diatur ke publik).
Mari kita lihat Contoh 3:
Test3.java
paket 1class myobject3 {clone objek yang dilindungi () melempar clonenotsupportedException {return super.clone (); }} paket 2Public class test3 memperluas myobject3 {public static void main (string args []) {myobject3 obj = new myobject3 (); obj.clone (); // Kompilasi kesalahan. Test3 tobj = test3 baru (); tobj.clone (); // compie ok. }} Di sini saya menggunakan kelas test3 untuk mewarisi myObject3. Perhatikan bahwa kedua kelas ini memiliki paket yang berbeda, jika tidak itu adalah kasus Contoh 2. Di kelas Test3, sebut metode klon () dari instance TOBJ dari kelas test3 dan mengkompilasi dan lulus. Dan juga memanggil metode klon () dari instance OBJ dari kelas MyObject3 dipanggil, dan kesalahan kompilasi!
Hasil yang tidak terduga, tidak bisakah metode yang dilindungi diakses oleh kelas yang diwariskan?
Harus jelas bahwa Class Test3 tidak mewarisi kelas MyObject3 (termasuk metode klonnya), sehingga Anda dapat memanggil metode klon Anda sendiri di kelas tes3. Namun, metode yang dilindungi dari kelas MyObject3 tidak terlihat oleh uji subclass BUN yang berbeda3.
Ini bagian lain dari "Java Sick Sutshell":
Akses yang dilindungi membutuhkan sedikit lebih banyak tenaga kerja. Misalkan Kelas A menyatakan bidang X yang dilindungi dan diperluas oleh Kelas B, yang didefinisikan dalam paket yang berbeda (poin terakhir ini penting). Kelas B mewarisi bidang X yang dilindungi, dan kodenya dapat mengakses bidang itu dalam instance B saat ini atau dalam contoh lain B yang dapat dirujuk oleh kode. Namun, ini tidak berarti bahwa kode Kelas B dapat mulai membaca bidang yang dilindungi dari contoh sewenang -wenang dari A! Jika suatu objek adalah instance dari A tetapi bukan contoh B, bidangnya jelas tidak diwarisi oleh B, dan kode Kelas B tidak dapat membacanya.
Ngomong -ngomong, banyak buku java di Cina umumnya dijelaskan dengan cara ini ketika memperkenalkan izin akses (berbagai bentuk dan konten yang konsisten):
Kontrol akses metode:
statis
1. Kata kunci statis (ingat ini dulu, lalu bacalah)
1) Metode statis dan variabel statis adalah objek yang termasuk dalam kelas tertentu, tetapi tidak untuk kelas.
2) Referensi ke metode statis dan variabel statis secara langsung direferensikan melalui nama kelas.
3) Metode non-statis dan variabel anggota non-statis tidak dapat dipanggil dalam metode statis. Kalau tidak, tidak apa -apa.
4) Variabel statis mirip dengan variabel global dalam bahasa lain dalam beberapa program, dan dapat diakses di luar kelas jika mereka tidak pribadi.
2. Kapan menggunakan statis
Saat kami membuat instance dari kelas (objek), kami biasanya menggunakan metode baru sehingga ruang data kelas ini akan dibuat dan metodenya dapat dipanggil.
Namun, kadang -kadang kami berharap bahwa meskipun kelas dapat dibuat dengan objek N (jelas ruang data dari objek N ini berbeda), beberapa data dari objek N ini adalah sama, yaitu, terlepas dari berapa banyak contoh kelas yang dimiliki, data memiliki salinan memori dari contoh ini (lihat Contoh 1). Ini adalah kasus dengan variabel statis.
Skenario lain adalah bahwa Anda ingin metode untuk tidak dikaitkan dengan objek kelas yang mengandungnya. Dengan kata lain, metode ini dapat dipanggil bahkan jika objek tidak dibuat. Penggunaan penting dari metode statis adalah menyebutnya tanpa membuat objek apa pun (lihat Contoh 2). Ini adalah kasus dengan metode statis.
Ada juga penggunaan khusus di kelas dalam. Biasanya, kelas normal tidak diizinkan untuk dinyatakan statis, hanya kelas dalam yang dapat melakukannya. Pada saat ini, kelas dalam ini dinyatakan sebagai statis dapat digunakan secara langsung sebagai kelas normal tanpa perlu contoh kelas luar (lihat Contoh 3). Ini adalah kasus dengan kelas statis.
Contoh 1
kelas publik tstatic {static int i; public tstatic () {i = 4; } public tstatic (int j) {i = j; } public static void main (string args []) {System.out.println (tstatic.i); Tstatic t = tstatic baru (5); // Nyatakan referensi objek dan instantiate. Saat ini i = 5 System.out.println (TI); Tstatic tt = tstatic baru (); // Nyatakan referensi objek dan instantiate. Saat ini i = 4 System.out.println (TI); System.out.println (tt.i); System.out.println (TI); }}
hasil:
05444
Variabel statis dibuat saat kelas dimuat. Selama kelas ada, variabel statis ada. Mereka harus diinisialisasi ketika didefinisikan. Dalam contoh di atas, saya tidak diinisialisasi, sehingga nilai awal default 0 akan diperoleh. Variabel statis hanya dapat diinisialisasi sekali, dan variabel statis hanya menerima inisialisasi terakhir.
Bahkan, ini masih menjadi masalah dengan banyak contoh berbagi variabel statis.
Contoh 2
Tidak dinyatakan statis
kelas classa {int b; public void ex1 () {} class classb {void ex2 () {int i; Classa a = new classa (); i = ab; // di sini akses ke variabel anggota b A.ex1 () melalui referensi objek; // Di sini akses ke fungsi anggota EX1 melalui referensi objek}}}
Dinyatakan sebagai statis
kelas classa {static int b; static void ex1 () {}} class classb {void ex2 () {int i; i = classa.b; // di sini akses ke variabel anggota b clasta.ex1 () melalui nama kelas; // Di sini akses ke fungsi anggota EX1 melalui nama kelas}} Saat menggunakan metode statis, hati-hati bahwa metode non-statis tidak dapat dipanggil dalam metode statis dan variabel anggota non-statis referensi (ini atau super tidak dapat dirujuk dengan cara apa pun dalam metode statis). Alasannya sangat sederhana. Untuk hal-hal statis, ketika JVM memuat kelas, ia membuka ruang statis ini dalam memori (sehingga dapat secara langsung direferensikan melalui nama kelas), dan pada saat ini, kelas di mana metode non-statis dan variabel anggota berada belum dipakai.
Jadi, jika Anda ingin menggunakan metode non-statis dan variabel anggota, Anda dapat secara langsung membuat kelas di mana metode atau variabel anggota terletak dalam metode statis. Begitulah public static void Main melakukannya.
Contoh 3
StaticCls kelas publik {public static void main (string [] args) {outercls.innercls oi = new Outerclsclscls (); // Tidak perlu untuk outercls baru sebelum ini}} class outercls {public static class innercls {innercls () {system.out.printcls {public static class innercls {innercls () {System.out.printcls }}}
hasil:
Innercls
3. Inisialisasi statis
Variabel yang ditentukan oleh statis akan diutamakan daripada variabel non-statis lainnya, terlepas dari urutan yang muncul. Blok kode statis (diikuti oleh sepotong kode) digunakan untuk melakukan inisialisasi variabel statis eksplisit. Kode ini hanya akan diinisialisasi sekali dan ketika kelas dimuat untuk pertama kalinya. Lihat contoh di bawah ini.
nilai kelas {static int c = 0; Value () {c = 15; } Value (int i) {c = i; } static void inc () {c ++; }} class count {public static void prt (string s) {System.out.println (s); } Nilai v = nilai baru (10); nilai statis v1, v2; static {prt ("di blok statis Cals Count v1.c =" + v1.c + "v2.c =" + v2.c); V1 = Nilai Baru (27); prt ("Di blok statis Cals Count v1.c =" + v1.c + "v2.c =" + v2.c); v2 = nilai baru (); prt ("Di blok statis Cals Count v1.c =" + v1.c + "v2.c =" + v2.c); }} kelas publik tstaticblock {public static void main (string [] args) {count ct = new count (); Count.prt ("Di utama:"); Count.prt ("ct.c =" + ct.vc); Count.prt ("v1.c =" + count.v1.c + "v2.c =" + count.v2.c); Count.v1.inc (); Count.prt ("v1.c =" + count.v1.c + "v2.c =" + count.v2.c); Count.prt ("ct.c =" + ct.vc); }}
hasil:
Di blok statis CALSS Count V1.C = 0 V2.C = 0in blok statis CALSS Count V1.C = 27 V2.C = 27 di blok statis CALSS Count v1.c = 15 v2.c = 15 di utama: ct.c = 10v1.c = 10 v2.c = 10v1.c = 11 v2.c = 10v1.
Apakah itu V, V1 atau V2, variabel anggota yang mereka operasikan adalah variabel statis yang sama c.
Dalam jumlah kelas, v1 dan v2 (nilai statis v1, v2;), kemudian menginisialisasi blok kode statis (statis {}), dan akhirnya menginisialisasi v.