Topik mengatakan sebagian besar - apa alasan untuk fakta bahwa metode statis tidak dapat dideklarasikan dalam sebuah antarmuka?
public interface ITest {
public static String test();
}
Kode di atas memberi saya kesalahan berikut (setidaknya di Eclipse): "Pengubah ilegal untuk metode antarmuka ITest.test (); hanya publik & abstrak yang diizinkan".
Jawaban:
Ada beberapa masalah yang berperan di sini. Yang pertama adalah masalah mendeklarasikan metode statis tanpa mendefinisikannya. Inilah perbedaan antara
dan
Yang pertama tidak mungkin karena alasan yang disebutkan Espo : Anda tidak tahu kelas implementasi mana yang merupakan definisi yang benar.
Jawa bisa mengizinkan yang terakhir; dan sebenarnya, mulai di Java 8, ya!
sumber
static
metode dalaminterface
. Metode haruspublic
.Alasan mengapa Anda tidak dapat memiliki metode statis di antarmuka terletak pada cara Java menyelesaikan referensi statis. Java tidak akan repot mencari instance kelas ketika mencoba untuk mengeksekusi metode statis. Ini karena metode statis tidak tergantung pada instance dan karenanya dapat dieksekusi langsung dari file kelas. Mengingat bahwa semua metode dalam antarmuka adalah abstrak, VM harus mencari implementasi antarmuka tertentu untuk menemukan kode di belakang metode statis sehingga dapat dieksekusi. Ini kemudian bertentangan dengan cara kerja resolusi metode statis dan akan memperkenalkan ketidakkonsistenan ke dalam bahasa.
sumber
Saya akan menjawab pertanyaan Anda dengan sebuah contoh. Misalkan kita memiliki kelas matematika dengan metode add statis. Anda akan memanggil metode ini seperti ini:
Jika Matematika adalah antarmuka dan bukan kelas, itu tidak bisa memiliki fungsi yang ditentukan. Dengan demikian, mengatakan sesuatu seperti Math.add (2, 3) tidak masuk akal.
sumber
Alasannya terletak pada prinsip-desain, bahwa java tidak memungkinkan multiple inheritance. Masalah dengan multiple inheritance dapat diilustrasikan dengan contoh berikut:
Sekarang apa yang terjadi jika Anda memanggil Cx ()? Apakah Ax () atau Bx () dieksekusi? Setiap bahasa dengan pewarisan berganda harus menyelesaikan masalah ini.
Antarmuka memungkinkan Java beberapa jenis pewarisan berganda terbatas. Untuk menghindari masalah di atas, mereka tidak diperbolehkan memiliki metode. Jika kita melihat masalah yang sama dengan antarmuka dan metode statis:
Masalah yang sama di sini, apa yang terjadi jika Anda memanggil Cx ()?
sumber
A
berisiint x(int z);
dan antarmukaB
mengandungstring x(int x);
? Apa arti darix(3)
antarmuka C?Metode statis bukan metode instan. Tidak ada konteks instance, oleh karena itu untuk mengimplementasikannya dari antarmuka tidak masuk akal.
sumber
Sekarang Java8 memungkinkan kita untuk mendefinisikan bahkan Metode Statis di Antarmuka.
Catatan: Metode dalam Antarmuka masih abstrak secara publik jika kita tidak secara eksplisit menggunakan kata kunci default / statis untuk menjadikannya Metode default dan metode Stat resp.
sumber
Ada jawaban yang sangat bagus dan ringkas untuk pertanyaan Anda di sini . (Itu menurut saya cara yang sangat mudah untuk menjelaskannya sehingga saya ingin menghubungkannya dari sini.)
sumber
Tampaknya metode statis di antarmuka mungkin didukung di Java 8 , well, solusi saya hanya mendefinisikan mereka di kelas dalam.
Teknik yang sama juga dapat digunakan dalam anotasi:
Kelas dalam harus selalu diakses dalam bentuk
Interface.fn...
alih-alihClass.fn...
, maka, Anda dapat menyingkirkan masalah ambigu.sumber
Antarmuka digunakan untuk polimorfisme, yang berlaku untuk Objek, bukan tipe. Oleh karena itu (sebagaimana telah dicatat) tidak masuk akal untuk memiliki anggota antarmuka statis.
sumber
Java 8 telah mengubah dunia Anda dapat memiliki metode statis dalam antarmuka tetapi memaksa Anda untuk memberikan implementasi untuk itu.
}
sumber
Kombinasi ilegal dari pengubah: statis dan abstrak
Jika anggota kelas dinyatakan sebagai statis, dapat digunakan dengan nama kelasnya yang terbatas pada kelas itu, tanpa membuat objek.
Jika anggota kelas dinyatakan sebagai abstrak, Anda harus mendeklarasikan kelas sebagai abstrak dan Anda harus memberikan implementasi anggota abstrak di kelas yang diwariskan (Sub-Kelas).
Anda perlu memberikan implementasi kepada anggota abstrak kelas di sub-kelas di mana Anda akan mengubah perilaku metode statis, juga dinyatakan sebagai abstrak yang terbatas pada kelas dasar, yang tidak benar
sumber
Karena metode statis tidak dapat diwarisi. Jadi tidak ada gunanya menempatkannya di antarmuka. Antarmuka pada dasarnya adalah kontrak yang harus diikuti oleh semua pelanggannya. Menempatkan metode statis di antarmuka akan memaksa pelanggan untuk mengimplementasikannya. yang sekarang menjadi bertentangan dengan fakta bahwa metode statis tidak dapat diwarisi.
sumber
Misalnya, Pembanding memiliki metode naturalOrder () statis.
Persyaratan bahwa antarmuka tidak dapat memiliki implementasi juga telah dilonggarkan. Antarmuka sekarang dapat mendeklarasikan implementasi metode "default", yang seperti implementasi normal dengan satu pengecualian: jika Anda mewarisi implementasi default dari antarmuka dan implementasi normal dari superclass, implementasi superclass akan selalu menjadi prioritas.
sumber
Mungkin contoh kode akan membantu, saya akan menggunakan C #, tetapi Anda harus dapat mengikuti.
Mari kita berpura-pura kita memiliki antarmuka yang disebut IPayable
Sekarang, kami memiliki dua kelas konkret yang mengimplementasikan antarmuka ini:
Sekarang, mari berpura-pura kita memiliki koleksi berbagai akun, untuk melakukan ini kita akan menggunakan daftar generik dari jenis IPayable
Sekarang, kami ingin membayar $ 50,00 ke semua akun itu:
Jadi sekarang Anda melihat bagaimana antarmuka sangat berguna.
Mereka digunakan hanya pada objek instantiated. Bukan di kelas statis.
Jika Anda melakukan pembayaran statis, saat perulangan melalui akun IPayable di akun ToPay, tidak akan ada cara untuk mengetahui apakah harus membayar panggilan di BusinessAcount atau CustomerAccount.
sumber