Pertanyaannya adalah di Jawa mengapa saya tidak bisa mendefinisikan metode statis abstrak? sebagai contoh
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
java
abstract-class
static-methods
hhafez
sumber
sumber
Jawaban:
Karena "abstrak" berarti: "Menerapkan fungsi tidak", dan "statis" berarti: "Ada fungsi bahkan jika Anda tidak memiliki turunan objek". Dan itu adalah kontradiksi yang logis.
sumber
abstract static
akan masuk akal. Ini akan menjadi metode objek kelas itu sendiri yang harus diimplementasikan objek subclass. Tentu saja, cara jawaban Anda benar, terlepas dari kekeliruan saya tentang bahasa.abstract static
: Fungsi X yang "diimplementasikan dalam subclass" bisa tidak pada saat yang sama akan "dieksekusi pada kelas" - hanya pada subclass . Dimana itu tidak abstrak lagi.static
tidak berarti "tidak kosong" - itu hanya konsekuensi dari Java yang tidak mengizinkan metode statis menjadi abstrak. Itu berarti "callable on the class." (Seharusnya berarti " hanya dapat dipanggil di kelas" tapi itu masalah lain.) Jika Java mendukungabstract static
metode saya berharap itu berarti bahwa metode 1) harus diimplementasikan oleh subclass, dan 2) adalah metode kelas dari subclass. Beberapa metode tidak masuk akal sebagai metode instan. Sayangnya Java tidak membiarkan Anda menentukan hal itu saat membuat kelas dasar abstrak (atau antarmuka).Desain bahasa yang buruk. Akan jauh lebih efektif untuk memanggil langsung metode abstrak statis daripada membuat contoh hanya untuk menggunakan metode abstrak itu. Terutama benar ketika menggunakan kelas abstrak sebagai solusi untuk enum ketidakmampuan untuk memperluas, yang merupakan contoh desain yang buruk. Semoga mereka bisa mengatasi keterbatasan itu dalam rilis berikutnya.
sumber
static
itu sendiri sudah merupakan pelanggaran ....Anda tidak dapat mengganti metode statis, jadi membuatnya abstrak akan menjadi tidak berarti. Selain itu, metode statis dalam kelas abstrak akan menjadi milik kelas itu, dan bukan kelas utama, jadi tidak bisa digunakan.
sumber
The
abstract
penjelasan untuk metode menunjukkan bahwa metode HARUS override dalam subclass.Di Jawa,
static
anggota (metode atau bidang) tidak dapat ditimpa oleh subclass (ini tidak selalu benar dalam bahasa berorientasi objek lainnya, lihat SmallTalk.)static
Anggota mungkin disembunyikan , tetapi secara fundamental berbeda dari yang ditimpa .Karena anggota statis tidak dapat diganti dalam subkelas,
abstract
anotasi tidak dapat diterapkan pada mereka.Selain itu - bahasa lain mendukung pewarisan statis, seperti halnya pewarisan contoh. Dari perspektif sintaksis, bahasa-bahasa tersebut biasanya membutuhkan nama kelas untuk dimasukkan dalam pernyataan. Sebagai contoh, di Jawa, dengan asumsi Anda menulis kode di ClassA, ini adalah pernyataan yang setara (jika methodA () adalah metode statis, dan tidak ada metode contoh dengan tanda tangan yang sama):
dan
Dalam SmallTalk, nama kelas bukan opsional, jadi sintaksnya adalah (perhatikan bahwa SmallTalk tidak menggunakan. Untuk memisahkan "subjek" dan "kata kerja", melainkan menggunakannya sebagai terminator statemend):
Karena nama kelas selalu diperlukan, "versi" yang benar dari metode selalu dapat ditentukan dengan melintasi hierarki kelas. Untuk apa nilainya, saya kadang-kadang kehilangan
static
warisan, dan digigit oleh kurangnya warisan statis di Jawa ketika saya mulai dengan itu. Selain itu, SmallTalk diketik bebek (dan karenanya tidak mendukung program-kontrak). Dengan demikian, SmallTalk tidak memilikiabstract
pengubah untuk anggota kelas.sumber
Saya juga mengajukan pertanyaan yang sama, ini sebabnya
Karena kelas Abstrak mengatakan, itu tidak akan memberikan implementasi dan mengizinkan subclass untuk memberikannya
jadi Subclass harus menimpa metode Superclass,
ATURAN NO 1 - Metode statis tidak dapat diganti
Karena anggota dan metode statis mengkompilasi elemen waktu, itu sebabnya Overloading (waktu kompilasi Polimorfisme) metode statis diperbolehkan daripada Overriding (Polimorfisme Runtime)
Jadi, mereka tidak bisa abstrak.
Tidak ada hal seperti abstrak statis <--- Tidak diizinkan di Java Universe
sumber
abstract static
melihat stackoverflow.com/questions/370962/… . The alasan sebenarnya mengapa Java tidak memungkinkan metode statis menjadi ditimpa karena Java tidak memungkinkan metode statis untuk menjadi ditimpa.foo(String)
tidak sama denganfoo(Integer)
- itu saja.Ini adalah desain bahasa yang buruk dan benar-benar tidak ada alasan mengapa itu tidak mungkin.
Sebenarnya, ini adalah implementasi bagaimana hal itu BISA dilakukan di JAWA :
================= Contoh lama di bawah ini =================
Cari getRequest, dan getRequestImpl ... setInstance dapat dipanggil untuk mengubah implementasi sebelum panggilan dibuat.
Digunakan sebagai berikut:
sumber
abstract static
metode seperti yang ditanyakan dalam pertanyaan dan Anda telah menulis dengan huruf tebal DAPAT DILAKUKAN DI JAWA . Ini benar-benar salah arah.Metode abstrak didefinisikan hanya sehingga dapat ditimpa dalam subkelas. Namun, metode statis tidak dapat diganti. Oleh karena itu, ini adalah kesalahan waktu kompilasi untuk memiliki metode abstrak dan statis.
Sekarang pertanyaan selanjutnya adalah mengapa metode statis tidak dapat ditimpa ??
Itu karena metode statis milik kelas tertentu dan bukan ke instansinya. Jika Anda mencoba menimpa metode statis Anda tidak akan mendapatkan kesalahan kompilasi atau runtime tetapi kompiler hanya akan menyembunyikan metode statis superclass.
sumber
Metode statis, menurut definisi, tidak perlu tahu
this
. Dengan demikian, itu tidak bisa menjadi metode virtual (yang kelebihan beban menurut informasi subclass dinamis tersedia melaluithis
); sebaliknya, kelebihan metode statis semata-mata didasarkan pada info yang tersedia pada waktu kompilasi (ini berarti: setelah Anda merujuk metode statis superclass, Anda memanggil metode superclass, tetapi tidak pernah metode subclass).Menurut ini, metode statis abstrak akan sangat berguna karena Anda tidak akan pernah memiliki referensi diganti oleh beberapa badan tertentu.
sumber
Saya melihat bahwa sudah ada miliaran jawaban Tuhan tetapi saya tidak melihat solusi praktis. Tentu saja ini adalah masalah nyata dan tidak ada alasan yang baik untuk mengecualikan sintaks ini di Jawa. Karena pertanyaan awal tidak memiliki konteks di mana ini mungkin diperlukan, saya memberikan konteks dan solusi:
Misalkan Anda memiliki metode statis di banyak kelas yang identik. Metode-metode ini memanggil metode statis yang spesifik kelas:
doWork()
metodeC1
danC2
identik. Mungkin ada banyak calsses ini:C3
C4
dll. Jikastatic abstract
diizinkan, Anda akan menghilangkan kode duplikat dengan melakukan sesuatu seperti:tetapi ini tidak akan dikompilasi karena
static abstract
kombinasi tidak diperbolehkan. Namun, ini dapat dielakkan denganstatic class
konstruk, yang diizinkan:Dengan solusi ini, satu-satunya kode yang diduplikasi adalah
sumber
C1.doWork()
atauC2.doWork()
Tapi Anda tidak bisa meneleponC.doWork()
. Juga dalam contoh yang Anda berikan, yang tidak akan berfungsi, anggaplah jika diizinkan, lalu bagaimana kelasC
menemukan implementasidoMoreWork()
? Akhirnya saya akan menyebut kode konteks Anda desain yang buruk. Mengapa? hanya karena Anda telah membuat fungsi terpisah untuk kode yang unik alih-alih membuat fungsi untuk kode yang umum dan kemudian menerapkan fungsi statis di kelasC
. Ini lebih mudah !!!Asumsikan ada dua kelas,
Parent
danChild
.Parent
adalahabstract
. Deklarasi tersebut adalah sebagai berikut:Ini berarti bahwa setiap instance
Parent
harus menentukan bagaimanarun()
dijalankan.Namun, anggaplah sekarang itu
Parent
tidak benarabstract
.Ini berarti
Parent.run()
akan menjalankan metode statis.Definisi
abstract
metode adalah "Metode yang dideklarasikan tetapi tidak diimplementasikan", yang berarti tidak mengembalikan apa pun itu sendiri.Definisi
static
metode adalah "Metode yang mengembalikan nilai yang sama untuk parameter yang sama terlepas dari instance yang dipanggil".Sebuah
abstract
nilai kembali metode ini akan berubah karena perubahan misalnya. Sebuahstatic
metode tidak akan. Sebuahstatic abstract
metode adalah cukup banyak metode di mana nilai kembali adalah konstan, tetapi tidak kembali apa-apa. Ini adalah kontradiksi yang logis.Juga, sebenarnya tidak ada banyak alasan untuk suatu
static abstract
metode.sumber
Kelas abstrak tidak dapat memiliki metode statis karena abstraksi dilakukan untuk mencapai BINDING DINAMIS sementara metode statis terikat secara fungsional dengan fungsinya. Metode statis berarti perilaku yang tidak bergantung pada variabel instan, jadi tidak ada instance / objek yang diperlukan. Hanya kelas. Metode statis milik kelas dan bukan objek. Mereka disimpan di area memori yang dikenal sebagai PERMGEN dari mana itu dibagi dengan setiap objek. Metode dalam kelas abstrak secara dinamis terikat dengan fungsinya.
sumber
Mendeklarasikan metode sebagai
static
cara kita dapat memanggil metode itu dengan nama kelasnya dan jika kelas ituabstract
juga, tidak masuk akal untuk memanggilnya karena tidak mengandung benda apa pun, dan karenanya kita tidak dapat mendeklarasikan metode sebagaistatic
danabstract
.sumber
Karena metode abstrak adalah milik kelas dan tidak dapat ditimpa oleh kelas pelaksana. Bahkan jika ada metode statis dengan tanda tangan yang sama, ia menyembunyikan metode tersebut, tidak menimpanya. Jadi tidak penting untuk menyatakan metode abstrak sebagai statis karena tidak akan pernah mendapatkan tubuh. Jadi, kompilasi kesalahan waktu.
sumber
Metode statis dapat dipanggil tanpa turunan dari kelas. Dalam contoh Anda, Anda dapat memanggil foo.bar2 (), tetapi tidak foo.bar (), karena untuk bilah Anda memerlukan sebuah instance. Kode berikut bisa digunakan:
Jika Anda memanggil metode statis, itu akan selalu dieksekusi kode yang sama. Dalam contoh di atas, bahkan jika Anda mendefinisikan ulang bar2 di ImplementsFoo, panggilan ke var.bar2 () akan menjalankan foo.bar2 ().
Jika bar2 sekarang tidak memiliki implementasi (itu artinya abstrak), Anda dapat memanggil metode tanpa implementasi. Itu sangat berbahaya.
sumber
Saya percaya saya telah menemukan jawaban untuk pertanyaan ini, dalam bentuk mengapa metode antarmuka (yang bekerja seperti metode abstrak di kelas induk) tidak bisa statis. Ini jawaban lengkapnya (bukan punyaku)
Pada dasarnya metode statis dapat diikat pada waktu kompilasi, karena untuk memanggilnya Anda perlu menentukan kelas. Ini berbeda dari metode instance, di mana kelas referensi dari mana Anda memanggil metode mungkin tidak diketahui pada waktu kompilasi (dengan demikian blok kode mana yang dipanggil hanya dapat ditentukan saat runtime).
Jika Anda memanggil metode statis, Anda sudah tahu kelas di mana itu diterapkan, atau setiap subclass langsung dari itu. Jika Anda mendefinisikan
Maka
Foo.bar();
panggilan apa pun jelas ilegal, dan Anda akan selalu menggunakannyaFoo2.bar();
.Dengan pemikiran ini, satu-satunya tujuan dari metode abstrak statis adalah untuk menegakkan subclass untuk menerapkan metode seperti itu. Anda mungkin awalnya berpikir ini SANGAT salah, tetapi jika Anda memiliki parameter tipe generik
<E extends MySuperClass>
akan lebih baik untuk menjamin melalui antarmuka yangE
bisa.doSomething()
. Perlu diingat bahwa karena tipe generik penghapusan hanya ada pada waktu kompilasi.Jadi, apakah akan bermanfaat? Ya, dan mungkin itu sebabnya Java 8 memungkinkan metode statis di antarmuka (meskipun hanya dengan implementasi standar). Mengapa tidak metode statis abstrak dengan implementasi default di kelas? Sederhananya karena metode abstrak dengan implementasi default sebenarnya adalah metode konkret.
Mengapa tidak metode abstrak / antarmuka statis tanpa implementasi standar? Rupanya, hanya karena cara Java mengidentifikasi blok kode mana yang harus dijalankan (bagian pertama dari jawaban saya).
sumber
Karena kelas abstrak adalah konsep OOPS dan anggota statis bukan bagian dari OOPS ....
Sekarang masalahnya kita dapat mendeklarasikan metode statis lengkap dalam antarmuka dan kita dapat menjalankan antarmuka dengan mendeklarasikan metode utama di dalam antarmuka
sumber
Gagasan memiliki metode statis abstrak adalah bahwa Anda tidak dapat menggunakan kelas abstrak tertentu secara langsung untuk metode itu, tetapi hanya turunan pertama yang akan diizinkan untuk menerapkan metode statis itu (atau untuk obat generik: kelas sebenarnya dari obat generik yang Anda gunakan). menggunakan).
Dengan begitu, Anda bisa membuat misalnya kelas abstrak sortableObject atau bahkan antarmuka dengan metode statis abstrak (otomatis), yang menentukan parameter opsi sortir:
Sekarang Anda dapat mendefinisikan objek yang dapat diurutkan yang dapat diurutkan berdasarkan jenis utama yang sama untuk semua objek ini:
Sekarang Anda dapat membuat
yang dapat mengambil jenis, membangun menu pop-up untuk memilih jenis untuk mengurutkan dan menggunakan daftar dengan mendapatkan data dari jenis itu, serta memiliki fungsi add yang, ketika jenis sortir telah dipilih, dapat otomatis -sort item baru masuk Perhatikan bahwa instance dari SortableList dapat langsung mengakses metode statis "T":
Masalah dengan harus menggunakan sebuah instance adalah bahwa SortableList mungkin belum memiliki item, tetapi sudah harus menyediakan pengurutan yang disukai.
Cheerio, Olaf.
sumber
Pertama, titik kunci tentang kelas abstrak - Kelas abstrak tidak dapat dipakai (lihat wiki ). Jadi, Anda tidak dapat membuat setiap instance dari kelas abstrak.
Sekarang, cara java menangani metode statis adalah dengan membagikan metode tersebut dengan semua instance dari kelas itu.
Jadi, jika Anda tidak dapat membuat instance kelas, kelas itu tidak dapat memiliki metode statis abstrak karena metode abstrak meminta untuk diperpanjang.
Ledakan.
sumber
Sesuai dokumen Java :
Di Java 8, bersama dengan metode standar, metode statis juga diizinkan dalam sebuah antarmuka. Ini membuatnya lebih mudah bagi kami untuk mengatur metode pembantu di perpustakaan kami. Kita dapat menyimpan metode statis khusus untuk antarmuka di antarmuka yang sama daripada di kelas yang terpisah.
Contoh yang bagus dari ini adalah:
dari pada
Contoh lain dari menggunakan metode statis juga diberikan dalam dokumen itu sendiri:
sumber
Karena 'abstrak' berarti metode ini dimaksudkan untuk dikesampingkan dan orang tidak dapat mengesampingkan metode 'statis'.
sumber
Metode biasa bisa abstrak ketika dimaksudkan untuk diganti oleh subclass dan dilengkapi dengan fungsionalitas. Bayangkan kelas
Foo
diperpanjang olehBar1, Bar2, Bar3
dll. Jadi, masing-masing akan memiliki versi sendiri dari kelas abstrak sesuai dengan kebutuhan mereka.Sekarang, metode statis menurut definisi adalah milik kelas, mereka tidak ada hubungannya dengan objek kelas atau objek subkelasnya. Mereka bahkan tidak membutuhkannya, mereka dapat digunakan tanpa membuat instance kelas. Oleh karena itu, mereka harus siap-untuk-pergi dan tidak dapat bergantung pada subclass untuk menambahkan fungsionalitas kepada mereka.
sumber
Karena abstrak adalah kata kunci yang diterapkan pada metode abstrak tidak menentukan tubuh. Dan jika kita berbicara tentang kata kunci statis itu milik area kelas.
sumber
karena jika Anda menggunakan anggota statis atau variabel statis di kelas itu akan memuat pada waktu pemuatan kelas.
sumber
Anda dapat melakukan ini dengan antarmuka di Java 8.
Ini adalah dokumentasi resmi tentangnya:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
sumber
Karena jika sebuah kelas memperluas kelas abstrak maka ia harus menimpa metode abstrak dan itu wajib. Dan karena metode statis adalah metode kelas yang diselesaikan pada waktu kompilasi sedangkan metode yang diganti adalah metode instan yang diselesaikan pada saat runtime dan mengikuti polimorfisme dinamis.
sumber