Saya baru saja menemukan antarmuka bersarang statis di basis kode kami.
class Foo {
public static interface Bar {
/* snip */
}
/* snip */
}
Saya belum pernah melihat ini sebelumnya. Pengembang asli berada di luar jangkauan. Karena itu saya harus bertanya kepada SO:
Apa yang dimaksud dengan semantik di belakang antarmuka statis? Apa yang akan berubah, jika saya menghapus static
? Mengapa ada orang yang melakukan hal ini?
Jawaban:
Kata kunci statis dalam contoh di atas adalah redundan (antarmuka bersarang secara otomatis "statis") dan dapat dihapus tanpa efek pada semantik; Saya akan merekomendasikan itu dihapus. Hal yang sama berlaku untuk "publik" pada metode antarmuka dan "final publik" pada bidang antarmuka - pengubah berlebihan dan hanya menambahkan kekacauan pada kode sumber.
Either way, pengembang hanya mendeklarasikan antarmuka bernama Foo.Bar. Tidak ada hubungan lebih lanjut dengan kelas terlampir, kecuali kode yang tidak dapat mengakses Foo tidak akan dapat mengakses Foo.Bar juga. (Dari kode sumber - bytecode atau refleksi dapat mengakses Foo.Bar bahkan jika Foo adalah paket-pribadi!)
Merupakan gaya yang dapat diterima untuk membuat antarmuka bersarang dengan cara ini jika Anda mengharapkannya hanya digunakan dari kelas luar, sehingga Anda tidak membuat nama tingkat atas yang baru. Sebagai contoh:
sumber
Pertanyaan telah dijawab, tetapi salah satu alasan bagus untuk menggunakan antarmuka bersarang adalah jika fungsinya terkait langsung dengan kelas yang ada di dalamnya. Contoh yang bagus untuk ini adalah a
Listener
. Jika Anda memiliki kelasFoo
dan Anda ingin kelas lain dapat mendengarkan acara di dalamnya, Anda bisa mendeklarasikan antarmuka bernamaFooListener
, yang ok, tetapi mungkin akan lebih jelas untuk mendeklarasikan antarmuka bersarang dan meminta kelas-kelas lain menerapkanFoo.Listener
( kelas bersarangFoo.Event
tidak buruk seiring dengan ini).sumber
java.util.Map.Entry
(yang merupakan antarmuka bersarang di antarmuka lain).Map.Entry
) atau kelas juga berada dalam paket itu. Saya mengatakan ini karena saya ingin menjaga kelas saya singkat dan to the point. Pembaca juga dapat melihat entitas apa yang terkait dengan kelas dengan melihat kelas-kelas dalam paket. Saya mungkin punya paketjava.collections.map
untuk peta. Ini tentang OO dan modularitas.java.util
memiliki terlalu banyak di dalamnya.util
seperticommon
- aroma IMOjava.util
tentu memiliki terlalu banyak di dalamnya. Yang mengatakan, saya tidak berpikir bahwa memecahnya menjadi paket berbutir halus seperti yang Anda sarankan juga ideal.java.util.MapEntry
luar paket sendiri. Refleks pertama: apa antarmuka yang terkait dengan kelas ini? Saya melihat ke dalam kelas. Kecuali tautan javadoc ke antarmuka ini, saya tidak tahu hubungan mereka. Plus orang tidak melihat paket impor. Setiap orang punya pendapat sendiri. Tidak ada yang benar, tidak ada yang salahAntarmuka anggota secara implisit statis. Pengubah statis dalam contoh Anda dapat dihapus tanpa mengubah semantik kode. Lihat juga Spesifikasi Bahasa Jawa 8.5.1. Deklarasi Tipe Anggota Statis
sumber
Antarmuka bagian dalam harus statis agar dapat diakses. Antarmuka tidak terkait dengan instance kelas, tetapi dengan kelas itu sendiri, sehingga akan diakses dengan
Foo.Bar
, seperti:Dalam banyak hal, ini tidak berbeda dari kelas dalam statis.
sumber
The interface isn't associated with instances of the class, but with the class itself
lebih jauh, saya tidak mengertiJawaban Jesse dekat, tapi saya pikir ada kode yang lebih baik untuk menunjukkan mengapa antarmuka internal mungkin berguna. Lihatlah kode di bawah ini sebelum Anda membaca. Dapatkah Anda menemukan mengapa antarmuka bagian dalam bermanfaat? Jawabannya adalah bahwa kelas DoSomethingAlready dapat dipakai dengan setiap kelas yang mengimplementasikan A dan C; bukan hanya Kebun Binatang kelas beton. Tentu saja, ini dapat dicapai bahkan jika AC tidak dalam, tetapi bayangkan menggabungkan nama yang lebih panjang (bukan hanya A dan C), dan melakukan ini untuk kombinasi lain (katakanlah, A dan B, C dan B, dll) dan Anda dengan mudah lihat bagaimana hal-hal di luar kendali. Belum lagi orang-orang yang meninjau pohon sumber Anda akan kewalahan oleh antarmuka yang hanya bermakna dalam satu kelas. Jadi, untuk meringkas,antarmuka bagian dalam memungkinkan pembangunan jenis khusus dan meningkatkan enkapsulasi mereka .
sumber
Zoo
tidak tidak mengimplementasikan antarmukaAC
, oleh karena itu, contohZoo
kaleng tidak diteruskan ke konstruktor dariDoSomethingAlready
yang mengharapkanAC
. Fakta yangAC
meluas keduanya,A
danC
, tidak menyiratkan bahwa kelas mengimplementasikanA
danC
secara ajaib juga mengimplementasikanAC
.Untuk menjawab pertanyaan Anda secara langsung, lihat Map.Entry.
Peta. Coba
juga ini mungkin berguna
Entri blog Static Nested Inerfaces
sumber
Biasanya saya melihat kelas dalam statis. Kelas dalam statis tidak dapat mereferensikan kelas yang berisi dimana kelas non-statis bisa. Kecuali Anda menjalankan beberapa tabrakan paket (sudah ada antarmuka yang disebut Bar dalam paket yang sama dengan Foo) Saya pikir saya akan membuatnya menjadi file sendiri. Ini juga bisa menjadi keputusan desain untuk menegakkan koneksi logis antara Foo dan Bar. Mungkin penulis bermaksud Bar hanya digunakan dengan Foo (meskipun antarmuka statis tidak akan menegakkan ini, hanya koneksi logis)
sumber
Jika Anda akan mengubah kelas Foo menjadi antarmuka Foo kata kunci "publik" pada contoh di atas juga akan berlebihan karena
sumber
Pada tahun 1998, Philip Wadler menyarankan perbedaan antara antarmuka statis dan antarmuka non-statis.
Misalnya, ia mengusulkan solusi untuk Masalah Ekspresi , yang merupakan ketidakcocokan antara ekspresi sebagai "seberapa banyak bahasa Anda dapat mengekspresikan" di satu sisi dan ekspresi sebagai "istilah yang Anda coba wakili dalam bahasa Anda" di sisi lain .
Contoh perbedaan antara antarmuka bersarang statis dan non-statis dapat dilihat pada kode sampelnya :
Sarannya tidak pernah berhasil di Java 1.5.0. Oleh karena itu, semua jawaban lain benar: tidak ada perbedaan untuk antarmuka bersarang statis dan non-statis.
sumber
Di Java, antarmuka statis / kelas memungkinkan antarmuka / kelas untuk digunakan seperti kelas tingkat atas, yaitu, dapat dideklarasikan oleh kelas lain. Jadi, Anda bisa melakukan:
Tanpa statis, di atas akan gagal dikompilasi. Keuntungannya adalah Anda tidak perlu file sumber baru hanya untuk mendeklarasikan antarmuka. Itu juga secara visual mengaitkan antarmuka Bar ke kelas Foo karena Anda harus menulis Foo.Bar dan menyiratkan bahwa kelas Foo melakukan sesuatu dengan contoh Foo.Bar.
Deskripsi tipe kelas di Jawa .
sumber
Static berarti bahwa setiap bagian kelas dari paket (proyek) dapat mengaksesnya tanpa menggunakan pointer. Ini dapat bermanfaat atau menghambat tergantung pada situasinya.
Contoh sempurna dari manfaat metode "statis" adalah kelas Matematika. Semua metode dalam Matematika bersifat statis. Ini berarti Anda tidak perlu keluar dari jalan Anda, membuat contoh baru, mendeklarasikan variabel dan menyimpannya dalam lebih banyak variabel, Anda bisa memasukkan data Anda dan mendapatkan hasilnya.
Statis tidak selalu berguna. Misalnya, jika Anda melakukan perbandingan kasus, Anda mungkin ingin menyimpan data dengan beberapa cara berbeda. Anda tidak dapat membuat tiga metode statis dengan tanda tangan yang identik. Anda memerlukan 3 contoh berbeda, non-statis, dan kemudian Anda bisa dan membandingkan, karena jika statis, data tidak akan berubah seiring dengan input.
Metode statis baik untuk pengembalian satu kali dan perhitungan cepat atau data yang mudah diperoleh.
sumber