Saya sedang membaca Panduan Programmer untuk Sertifikasi SCJP Java ™ oleh Khalid Mughal.
Di bab Warisan, dijelaskan itu
Warisan anggota terkait erat dengan aksesibilitas yang mereka nyatakan. Jika anggota superclass dapat diakses dengan nama sederhananya di subclass (tanpa menggunakan sintaks tambahan seperti super), anggota itu dianggap mewarisi.
Itu juga menyebutkan bahwa metode statis tidak diwariskan. Tetapi kode di bawah ini sangat bagus:
class A
{
public static void display()
{
System.out.println("Inside static method of superclass");
}
}
class B extends A
{
public void show()
{
// This works - accessing display() by its simple name -
// meaning it is inherited according to the book.
display();
}
}
Bagaimana saya bisa langsung menggunakan display()
di kelas B
? Bahkan lebih, B.display()
juga berhasil.
Apakah penjelasan buku hanya berlaku untuk metode contoh?
java
inheritance
static
Ahli algoritma
sumber
sumber
Jawaban:
Semua metode yang dapat diakses diwarisi oleh subclass.
Dari Tutorial Sun Java :
Satu-satunya perbedaan dengan metode statis (kelas) yang diwarisi dan metode non-statis (instance) yang diwarisi adalah bahwa saat Anda menulis metode statis baru dengan tanda tangan yang sama, metode statis lama hanya disembunyikan, tidak diganti.
Dari halaman tentang perbedaan antara mengganti dan menyembunyikan.
sumber
Anda dapat mengalami perbedaan dalam kode berikut, yang merupakan sedikit modifikasi pada kode Anda.
class A { public static void display() { System.out.println("Inside static method of superclass"); } } class B extends A { public void show() { display(); } public static void display() { System.out.println("Inside static method of this class"); } } public class Test { public static void main(String[] args) { B b = new B(); // prints: Inside static method of this class b.display(); A a = new B(); // prints: Inside static method of superclass a.display(); } }
Hal ini karena metode statis adalah metode kelas.
A.display () dan B.display () akan memanggil metode kelas masing-masing.
sumber
Jika itu yang sebenarnya dikatakan buku itu, itu salah. [1]
The Java Language Specification # 8.4.8 negara:
[1] Tidak disebutkan dalam salinan saya, edisi pertama, 2000.
sumber
B.display () berfungsi karena deklarasi statik membuat metode / anggota menjadi milik kelas, dan bukan instance kelas tertentu (alias Objek). Anda dapat membaca lebih lanjut di sini .
Hal lain yang perlu diperhatikan adalah Anda tidak dapat mengganti metode statis, Anda dapat meminta subkelas Anda mendeklarasikan metode statis dengan tanda tangan yang sama, tetapi perilakunya mungkin berbeda dari yang Anda harapkan. Ini mungkin alasan mengapa tidak dianggap sebagai warisan. Anda dapat melihat skenario bermasalah dan penjelasannya di sini .
sumber
Metode statis di Java diwariskan, tetapi tidak dapat diganti. Jika Anda mendeklarasikan metode yang sama dalam subclass, Anda menyembunyikan metode superclass alih-alih menimpanya. Metode statis tidak polimorfik. Pada saat kompilasi, metode statis akan ditautkan secara statis.
Contoh:
public class Writer { public static void write() { System.out.println("Writing"); } } public class Author extends Writer { public static void write() { System.out.println("Writing book"); } } public class Programmer extends Writer { public static void write() { System.out.println("Writing code"); } public static void main(String[] args) { Writer w = new Programmer(); w.write(); Writer secondWriter = new Author(); secondWriter.write(); Writer thirdWriter = null; thirdWriter.write(); Author firstAuthor = new Author(); firstAuthor.write(); } }
Anda akan mendapatkan yang berikut ini:
sumber
Metode statis diwariskan di Java tetapi tidak mengambil bagian dalam polimorfisme. Jika kita mencoba untuk menimpa metode statik, mereka hanya akan menyembunyikan metode statik superclass daripada menimpanya.
sumber
Konsep ini tidak semudah kelihatannya. Kita dapat mengakses anggota statis tanpa pewarisan, yaitu hubungan-HasA. Kita dapat mengakses anggota statis dengan memperluas kelas induk juga. Itu tidak menyiratkan bahwa itu adalah relasi ISA (Warisan). Sebenarnya anggota statis adalah milik kelas, dan statis bukanlah pengubah akses. Selama pengubah akses mengizinkan untuk mengakses anggota statis, kita dapat menggunakannya di kelas lain. Seperti jika bersifat publik maka akan dapat diakses di dalam paket yang sama dan juga di luar paket. Untuk pribadi kami tidak dapat menggunakannya di mana pun. Secara default, kami hanya dapat menggunakannya di dalam paket. Tapi untuk melindungi kita harus memperluas kelas super. Jadi mendapatkan metode statis ke kelas lain tidak bergantung pada status Statis. Itu tergantung pada pengubah Access. Jadi menurut saya, Anggota statis dapat mengakses jika pengubah akses mengizinkan. Jika tidak, kita dapat menggunakannya seperti yang kita gunakan oleh relasi Hasa. Dan memiliki hubungan bukan warisan. Sekali lagi kami tidak dapat mengganti metode statis. Jika kita dapat menggunakan metode lain tetapi tidak dapat menimpanya, maka itu adalah hubungan-HasA. Jika kita tidak bisa menimpanya, itu tidak akan menjadi warisan, jadi penulisnya 100% benar.
sumber
Metode statis diturunkan dalam subclass tetapi bukan polimorfisme. Saat Anda menulis implementasi metode statis, metode kelas induknya disembunyikan, bukan diganti. Pikirkan, jika tidak diwariskan lalu bagaimana Anda dapat mengakses tanpa
classname.staticMethodname();
?sumber
Semua anggota publik dan yang dilindungi dapat diwarisi dari kelas mana pun sementara anggota default atau paket juga dapat diwarisi dari kelas dalam paket yang sama dengan kelas super. Itu tidak tergantung apakah itu anggota statis atau non statis.
Tetapi juga benar bahwa fungsi anggota statis tidak mengambil bagian dalam pengikatan dinamis. Jika tanda tangan dari metode statis tersebut sama di kelas induk dan anak maka konsep Shadowing berlaku, bukan polimorfisme.
sumber
Anda dapat mengganti metode statis, tetapi jika Anda mencoba menggunakan polimorfisme, metode tersebut bekerja sesuai dengan cakupan kelas (Bertentangan dengan yang biasanya kita harapkan).
public class A { public static void display(){ System.out.println("in static method of A"); } } public class B extends A { void show(){ display(); } public static void display(){ System.out.println("in static method of B"); } } public class Test { public static void main(String[] args){ B obj =new B(); obj.show(); A a_obj=new B(); a_obj.display(); } }
DALAM kasus pertama, o / p adalah "dalam metode statis B" # berhasil menimpa Dalam kasus kedua, o / p adalah "dalam metode statis A" # Metode statis - tidak akan mempertimbangkan polimorfisme
sumber
Kita dapat mendeklarasikan metode statis dengan tanda tangan yang sama di subclass, tetapi itu tidak dianggap menimpa karena tidak akan ada polimorfisme run-time. Karena semua anggota statis kelas dimuat pada saat pemuatan kelas, jadi putuskan saat kompilasi waktu (overriding at run time) Oleh karena itu jawabannya adalah 'Tidak'.
sumber
Banyak yang menyuarakan jawaban mereka dengan kata-kata. Ini adalah penjelasan tambahan dalam kode:
public class A { public static void test() { System.out.println("A"); } public static void test2() { System.out.println("Test"); } } public class B extends A { public static void test() { System.out.println("B"); } } // Called statically A.test(); B.test(); System.out.println(); // Called statically, testing static inheritance A.test2(); B.test2(); System.out.println(); // Called via instance object A a = new A(); B b = new B(); a.test(); b.test(); System.out.println(); // Testing inheritance via instance call a.test2(); b.test2(); System.out.println(); // Testing whether calling static method via instance object is dependent on compile or runtime type ((A) b).hi(); System.out.println(); // Testing whether null instance works A nullObj = null; nullObj.hi();
Hasil:
Karena itu, inilah kesimpulannya:
null
instance. Dugaan saya adalah bahwa kompilator akan menggunakan tipe variabel untuk menemukan kelas selama kompilasi, dan menerjemahkannya ke panggilan metode statis yang sesuai.sumber
Anggota statis adalah anggota universal. Mereka bisa diakses dari mana saja.
sumber
Anggota statis tidak akan diturunkan ke subkelas karena pewarisan hanya untuk anggota non-statis .. Dan anggota statis akan dimuat di dalam kumpulan statis oleh pemuat kelas. Pewarisan hanya untuk anggota yang dimuat di dalam objek
sumber