Mengapa semua bidang dalam antarmuka secara implisit bersifat statis dan final?

100

Saya hanya mencoba memahami mengapa semua bidang yang ditentukan dalam Antarmuka secara implisit staticdan final. Ide untuk menjaga bidang staticmasuk akal bagi saya karena Anda tidak dapat memiliki objek antarmuka tetapi mengapa mereka final(secara implisit)?

Ada yang tahu mengapa desainer Java pergi dengan membuat bidang dalam antarmuka staticdan final?

peakit
sumber
Untuk catatan untuk saya sendiri: Ini statis karena bidang antarmuka tidak akan menjadi bagian dari objek yang mengimplementasikannya.
Hujan

Jawaban:

126

Antarmuka tidak boleh memiliki perilaku atau status karena hanya dimaksudkan untuk menentukan kontrak interaksi, tanpa detail implementasi. 'Tidak ada perilaku' diterapkan dengan tidak mengizinkan badan metode / konstruktor atau blok inisialisasi statis / instance. 'Tidak ada status' diberlakukan dengan hanya mengizinkan kolom final statis. Oleh karena itu, kelas dapat memiliki status (status statis), tetapi status instance tidak disimpulkan oleh antarmuka.

BTW: Konstanta di Java ditentukan oleh bidang akhir statis (dan menurut ketentuan, nama tersebut menggunakan UPPER_CASE_AND_UNDERSCORES).

Adriaan Koster
sumber
54
Tidak selalu benar bahwa bidang akhir adalah konstanta; itu hanya dijamin untuk tipe primitif. Secara umum, kata kunci terakhir hanya berarti bahwa lokasi memori tidak akan berubah.
Muncul
8
Saya tidak mengatakan bidang akhir adalah konstanta, hanya konstanta adalah bidang akhir. Perhatikan bahwa itu diizinkan untuk menempatkan bidang final statis non-primitif dalam sebuah antarmuka. Meskipun konten bidang itu mungkin berubah, rujukan ke bidang itu tetap.
Adriaan Koster
1
@AdriaanKoster Anda mengatakan dengan tepat bahwa bidang terakhir adalah konstan: Tidak ada status yang diberlakukan hanya dengan mengizinkan konstanta. - kalimat ini menyiratkan bahwa semua bidang akhir adalah konstan. Anda mungkin mencoba untuk memperdebatkan lebih lanjut tentang kata-kata yang Anda gunakan, tetapi jelas pernyataan Anda menyesatkan.
Tomáš Zato - Kembalikan Monica
2
Itu pasti kecerdasan saya yang memudar, tetapi setelah enam tahun melihat jawaban ini, yang kebetulan menjadi jawaban saya yang paling banyak mencetak, saya masih tidak memahami pernyataannya. Tolong sarankan kata yang berbeda karena saya tidak melihat ada yang salah.
Adriaan Koster
Mungkin itu adalah niat dari desainer java untuk membuat antarmuka tanpa kewarganegaraan, tetapi mereka gagal karena bidang instance dapat menjadi kelas yang dapat dimodifikasi. Alih-alih mengakui bahwa mereka gagal, mereka memilih untuk memaksa field instance static final, yang sedekat mungkin dengan real (sebenarnya adalah C / C ++) constseperti yang Anda dapatkan di java. Sayangnya ini implisit dan dapat menyebabkan kebingungan bagi non-ahli. (Saya baru menyadari bahwa itu statickarena saya mengamati perilaku yang tidak diinginkan. Saya mengetahui bahwa itu finalhanya dari jawaban ini.)
bukan-pengguna
27

Alasan untuk menjadi final

Penerapan apa pun dapat mengubah nilai bidang jika tidak ditentukan sebagai final. Kemudian mereka akan menjadi bagian dari implementasi. Antarmuka adalah spesifikasi murni tanpa implementasi apa pun.

Alasan untuk menjadi static

Jika mereka statis, maka mereka milik antarmuka, dan bukan objek, atau jenis waktu proses dari objek.

Gurpreet singh sidhuu
sumber
18

Ada beberapa poin yang dipoles di sini:

Hanya karena kolom dalam antarmuka bersifat final statis secara implisit, tidak berarti kolom tersebut harus berupa konstanta waktu kompilasi, atau bahkan tidak dapat diubah. Anda dapat mendefinisikan mis

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(Berhati-hatilah bahwa melakukan ini di dalam definisi anotasi dapat membingungkan javac , yang berkaitan dengan fakta bahwa yang di atas sebenarnya mengompilasi ke penginisialisasi statis.)

Juga, alasan pembatasan ini lebih gaya daripada teknis, dan banyak orang ingin melihatnya santai .

Jesse Glick
sumber
9

Kolom harus statis karena tidak boleh abstrak (seperti metode can). Karena tidak bisa abstrak, pelaksana tidak akan bisa secara logis menyediakan implementasi bidang yang berbeda.

Bidang harus final, saya pikir, karena bidang dapat diakses oleh pelaksana yang berbeda memungkinkan mereka untuk diubah mungkin bermasalah (seperti sinkronisasi). Juga untuk menghindarinya untuk diimplementasikan kembali (disembunyikan).

Hanya pikiranku.

NawaMan
sumber
NawMan, penjelasan Anda tentang "The felds must be static ..." tidak masuk akal. Tapi Anda benar tentang "Ladang harus final ..."
peakit
1
Saya tidak berpikir dia benar tentang alasan mengapa lapangan harus final. Mengizinkan pelaksana yang berbeda untuk mengubah bidang tidak bermasalah, karena jika tidak, warisan akan bermasalah. Bidang harus final, seperti yang dikatakan Adriaan, karena antarmuka adalah, dan seharusnya, tanpa negara. Antarmuka dengan status pada dasarnya harus berupa kelas abstrak.
Axelle Ziegler
Jika Anda memiliki public staticbidang yang tidak final, findbugs akan mengeluh (benar!).
Tom Hawtin - tackline
2

Saya menganggap persyaratan bahwa bidang menjadi final sebagai terlalu membatasi dan kesalahan oleh desainer bahasa Java. Ada kalanya, misalnya penanganan pohon, ketika Anda perlu menyetel konstanta dalam implementasi yang diperlukan untuk melakukan operasi pada objek dengan tipe antarmuka. Memilih jalur kode pada kelas pelaksana adalah sebuah kludge. Solusi yang saya gunakan adalah mendefinisikan fungsi antarmuka dan mengimplementasikannya dengan mengembalikan literal:

public interface iMine {
    String __ImplementationConstant();
    ...
}

public class AClass implements iMine {
    public String __ImplementationConstant(){
        return "AClass value for the Implementation Constant";
    }
    ...
}

public class BClass implements iMine {
    public String __ImplementationConstant(){
        return "BClass value for the Implementation Constant";
    }
    ...
}

Namun, akan lebih sederhana, lebih jelas dan tidak terlalu rentan terhadap implementasi yang menyimpang untuk menggunakan sintaks ini:

public interface iMine {
    String __ImplementationConstant;
    ...
}

public class AClass implements iMine {
    public static String __ImplementationConstant =
        "AClass value for the Implementation Constant";
    ...
}

public class BClass implements iMine {
    public static String __ImplementationConstant =
        "BClass value for the Implementation Constant";
    ...
}
Carl Klapper
sumber
Anda tampaknya lebih banyak mengeluh tentang bidang yang statis daripada menjadi final.
Daniel Yankowsky
0

Spesifikasi, kontrak ... Instruksi mesin untuk akses lapangan menggunakan alamat objek ditambah offset lapangan. Karena kelas dapat mengimplementasikan banyak antarmuka, tidak ada cara untuk membuat bidang antarmuka non-final memiliki offset yang sama di semua kelas yang memperluas antarmuka ini. Oleh karena itu, mekanisme yang berbeda untuk akses bidang harus diterapkan: dua akses memori (dapatkan offset bidang, dapatkan nilai bidang), bukan satu plus pemeliharaan jenis tabel bidang virtual (analog dari tabel metode virtual). Kira mereka hanya tidak ingin mempersulit jvm untuk fungsionalitas yang dapat dengan mudah disimulasikan melalui hal-hal yang ada (metode).

Dalam scala kita dapat memiliki bidang di antarmuka, meskipun secara internal diterapkan seperti yang saya jelaskan di atas (sebagai metode).

Yaroslav
sumber
-1

static:

Apa-apa (variabel atau metode) yang staticdi Jawa dapat dipanggil sebagai Classname.variablenameatau Classname.methodnameatau langsung. Tidak wajib untuk memanggilnya hanya dengan menggunakan nama objek.

Dalam antarmuka, objek tidak dapat dideklarasikan dan staticmemungkinkan untuk memanggil variabel hanya melalui nama kelas tanpa perlu nama objek.

final:

Ini membantu mempertahankan nilai konstan untuk variabel karena tidak dapat diganti dalam subkelasnya.

Sabika
sumber