Misalkan Anda memiliki dua antarmuka:
interface Readable {
public void read();
}
interface Writable {
public void write();
}
Dalam beberapa kasus objek implementasi hanya dapat mendukung salah satunya, tetapi dalam banyak kasus implementasi akan mendukung kedua antarmuka. Orang-orang yang menggunakan antarmuka harus melakukan sesuatu seperti:
// can't write to it without explicit casting
Readable myObject = new MyObject();
// can't read from it without explicit casting
Writable myObject = new MyObject();
// tight coupling to actual implementation
MyObject myObject = new MyObject();
Tidak satu pun dari opsi ini yang sangat nyaman, terlebih lagi ketika mempertimbangkan bahwa Anda menginginkan ini sebagai parameter metode.
Salah satu solusinya adalah dengan mendeklarasikan antarmuka pembungkus:
interface TheWholeShabam extends Readable, Writable {}
Tetapi ini memiliki satu masalah khusus: semua implementasi yang mendukung Readable dan Writable harus mengimplementasikan TheWholeShabam jika mereka ingin kompatibel dengan orang yang menggunakan antarmuka. Meskipun tidak menawarkan apa pun selain jaminan kehadiran kedua antarmuka.
Apakah ada solusi bersih untuk masalah ini atau haruskah saya menggunakan antarmuka pembungkus?
MEMPERBARUI
Sebenarnya seringkali diperlukan untuk memiliki objek yang dapat dibaca dan ditulis sehingga memisahkan kekhawatiran dalam argumen tidak selalu merupakan solusi bersih.
UPDATE2
(diekstraksi sebagai jawaban sehingga lebih mudah untuk mengomentari)
UPDATE3
Berhati-hatilah karena penggunaan utama untuk ini bukan stream (walaupun mereka juga harus didukung). Streaming membuat perbedaan yang sangat spesifik antara input dan output dan ada pemisahan tanggung jawab yang jelas. Sebaliknya, pikirkan sesuatu seperti bytebuffer di mana Anda memerlukan satu objek yang dapat Anda tulis dan baca, satu objek yang memiliki keadaan yang sangat spesifik yang melekat padanya. Objek-objek ini ada karena mereka sangat berguna untuk beberapa hal seperti asynchronous I / O, encodings, ...
UPDATE4
Salah satu hal pertama yang saya coba adalah sama dengan saran yang diberikan di bawah ini (periksa jawaban yang diterima) tetapi ternyata terlalu rapuh.
Misalkan Anda memiliki kelas yang harus mengembalikan tipe:
public <RW extends Readable & Writable> RW getItAll();
Jika Anda memanggil metode ini, RW generik ditentukan oleh variabel yang menerima objek, jadi Anda perlu cara untuk menggambarkan var ini.
MyObject myObject = someInstance.getItAll();
Ini akan berfungsi tetapi sekali lagi mengikatnya ke implementasi dan mungkin benar-benar membuang classcastexeption saat runtime (tergantung pada apa yang dikembalikan).
Selain itu jika Anda ingin variabel kelas dari tipe RW, Anda perlu mendefinisikan generik di tingkat kelas.