Saya telah bermain-main dengan pengubah dengan metode statis dan menemukan perilaku yang aneh.
Seperti yang kita ketahui, metode statis tidak dapat diganti, karena metode tersebut dikaitkan dengan kelas daripada instance.
Jadi jika saya memiliki potongan di bawah ini, itu dapat dikompilasi dengan baik
//Snippet 1 - Compiles fine
public class A {
static void ts() {
}
}
class B extends A {
static void ts() {
}
}
Tetapi jika saya menyertakan pengubah terakhir ke metode statis di kelas A, maka kompilasi gagal ts () di B tidak dapat menggantikan ts () di A; metode yang diganti adalah final statis .
Mengapa ini terjadi ketika metode statis tidak dapat diganti sama sekali?
Jawaban:
Metode statis tidak dapat diganti, tetapi dapat disembunyikan. The
ts()
Metode B tidak mengesampingkan (tidak tunduk polimorfisme) yangts()
dari A tetapi akan menyembunyikannya. Jika Anda memanggilts()
dalam B (BUKANA.ts()
atauB.ts()
... hanyats()
), yang B akan dipanggil dan bukan A. Karena ini tidak terkena polimorfisme, panggilants()
di A tidak akan pernah dialihkan ke di B.Kata kunci
final
akan menonaktifkan metode agar tidak disembunyikan. Jadi mereka tidak dapat disembunyikan dan upaya untuk melakukannya akan menghasilkan kesalahan kompilator.Semoga ini membantu.
sumber
A#ts
sedang diwariskan dan metode seperti itu sudah adaB
, hanya memiliki dua metode dengan tanda tangan yang sama dan pengubah yang berbeda (final
) tidak akan berfungsi sebagai kelebihan beban .. Saya berharap dapat memikirkan pesan sederhana untuk iniIni tidak sepenuhnya benar. Kode contoh benar-benar berarti bahwa metode ts di B menyembunyikan metode ts di A. Jadi itu tidak sepenuhnya menimpa. Di Javaranch ada penjelasan yang bagus.
sumber
Metode statis milik kelas, bukan instance.
A.ts()
danB.ts()
akan selalu menjadi metode terpisah.Masalah sebenarnya adalah Java memungkinkan Anda memanggil metode statis pada objek instance. Metode statis dengan tanda tangan yang sama dari kelas induk disembunyikan ketika dipanggil dari turunan subkelas. Namun, Anda tidak dapat mengganti / menyembunyikan metode terakhir .
Anda akan mengira pesan kesalahan akan menggunakan kata tersembunyi, bukan diganti ...
sumber
Anda mungkin menemukan diri Anda dalam posisi untuk berpikir tentang membuat final metode statis, dengan mempertimbangkan hal-hal berikut:
Memiliki kelas-kelas berikut:
Sekarang cara yang 'benar' untuk memanggil metode ini adalah
yang akan menghasilkan
AB
tetapi Anda juga bisa memanggil metode pada instance:yang akan menghasilkan
AB
juga.Sekarang pertimbangkan yang berikut:
yang akan mencetak
A
. Itu mungkin mengejutkan Anda karena Anda benar-benar memiliki objek kelasB
. Tetapi karena Anda memanggilnya dari referensi tipeA
, itu akan memanggilA.ts()
. Anda dapat mencetakB
dengan kode berikut:Dalam kedua kasus, objek yang Anda miliki sebenarnya dari kelas
B
. Tetapi bergantung pada penunjuk yang menunjuk ke objek, Anda akan memanggil metode dariA
atau dariB
.Sekarang katakanlah Anda adalah pengembang kelas
A
dan Anda ingin mengizinkan sub-pengelompokan. Tetapi Anda benar-benar menginginkan metodets()
, kapan pun dipanggil, bahkan dari subclass, yaitu melakukan apa yang Anda inginkan dan tidak disembunyikan oleh versi subclass. Kemudian Anda bisa membuatnyafinal
dan mencegahnya disembunyikan di subclass. Dan Anda dapat yakin bahwa kode berikut akan memanggil metode dari kelas AndaA
:Oke, harus diakui entah bagaimana dibangun, tapi mungkin masuk akal untuk beberapa kasus.
Anda tidak boleh memanggil metode statis pada instance tetapi langsung di kelas - maka Anda tidak akan mengalami masalah itu. Juga IntelliJ IDEA misalnya akan menampilkan peringatan, jika Anda memanggil metode statis pada sebuah instance dan juga jika Anda membuat metode statis final.
sumber
Metode ts () di B tidak menimpa metode ts () di A, itu hanya metode lain. Kelas B tidak melihat metode ts () di A karena bersifat statis, oleh karena itu kelas B dapat mendeklarasikan metodenya sendiri yang disebut ts ().
Namun, jika metode tersebut final, maka compiler akan mengambil bahwa ada metode ts () di A yang tidak boleh diganti di B.
sumber
Saya pikir kesalahan kompilasi cukup menyesatkan di sini. Seharusnya tidak ada kata "metode yang diganti adalah final statis", tetapi seharusnya mengatakan "metode yang diganti adalah final.". Pengubah statis tidak relevan di sini.
sumber
Metode statis tidak dapat diganti di Java, tidak seperti metode non-statis. Tetapi mereka diwariskan seperti anggota data statis dan non-statis. Itulah mengapa metode non-statis dengan nama yang sama tidak dapat dibuat di kelas induk
Kata
final
kunci memastikan bahwa tubuh metode tertentu dijalankan setiap kali panggilan ke metode. Sekarang jika metode statis dibuat di kelas anak dengan nama yang sama dan panggilan ke metode dibuat, metode di subkelas dijalankan yang seharusnya tidak terjadi jika final diawali sebelum nama metode statis di kelas induk . Oleh karena itu kata kunci terakhir membatasi pembuatan metode dengan nama yang sama di kelas anak.sumber