Jika suatu tipe mengimplementasikan dua antarmuka, dan masing-masing interface
mendefinisikan metode yang memiliki tanda tangan yang identik, maka pada dasarnya hanya ada satu metode, dan mereka tidak dapat dibedakan. Jika, katakanlah, kedua metode memiliki tipe pengembalian yang saling bertentangan, maka itu akan menjadi kesalahan kompilasi. Ini adalah aturan umum tentang pewarisan, metode pengesampingan, penyembunyian, dan deklarasi, dan berlaku juga untuk kemungkinan konflik tidak hanya antara 2 interface
metode yang diwariskan , tetapi juga metode interface
dan super class
, atau bahkan hanya konflik karena penghapusan jenis obat generik.
Contoh kompatibilitas
Berikut adalah contoh di mana Anda memiliki interface Gift
, yang memiliki present()
metode (seperti dalam, menyajikan hadiah), dan juga interface Guest
, yang juga memiliki present()
metode (seperti dalam, tamu hadir dan tidak absen).
Presentable johnny
keduanya a Gift
dan a Guest
.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
Cuplikan di atas mengkompilasi dan menjalankan.
Perhatikan bahwa hanya ada satu yang @Override
diperlukan !!! . Ini karena Gift.present()
dan Guest.present()
" @Override
-equivalent" ( JLS 8.4.2 ).
Dengan demikian, johnny
hanya memiliki satu implementasi dari present()
, dan tidak peduli bagaimana Anda memperlakukan johnny
, apakah sebagai Gift
atau sebagai Guest
, hanya ada satu metode untuk memohon.
Contoh ketidakcocokan
Berikut adalah contoh di mana kedua metode yang diwariskan TIDAK @Override
-setara:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
Ini lebih lanjut menegaskan bahwa mewarisi anggota dari interface
harus mematuhi aturan umum deklarasi anggota. Di sini kita memiliki Gift
dan Guest
mendefinisikan present()
dengan jenis pengembalian yang tidak kompatibel: satu sama void
lain boolean
. Untuk alasan yang sama bahwa Anda tidak bisa void present()
dan boolean present()
dalam satu tipe, contoh ini menghasilkan kesalahan kompilasi.
Ringkasan
Anda dapat mewarisi metode-metode yang sama @Override
, tunduk pada persyaratan metode override dan persembunyian yang biasa. Karena mereka ADALAH @Override
-setara, efektif hanya ada satu metode untuk melaksanakan, dan dengan demikian tidak ada yang membedakan / memilih dari.
Compiler tidak harus mengidentifikasi metode mana untuk antarmuka yang mana, karena begitu mereka ditentukan- @Override
sama, mereka adalah metode yang sama.
Menyelesaikan potensi ketidakcocokan mungkin merupakan tugas yang rumit, tapi itu masalah lain sama sekali.
Referensi
default
metode di Jawa 8.Foo
danBar
. Pada dasarnya Anda meminta kelas Anda mengimplementasikan salah satu antarmuka, misalnyaFoo
, dan memberikanBar asBar()
metode untuk mengembalikan kelas dalam yang mengimplementasikanBar
antarmuka kedua . Tidak sempurna karena kelas Anda pada akhirnya bukan "Bar", tetapi bisa berguna dalam beberapa keadaan.Ini ditandai sebagai duplikat untuk pertanyaan ini /programming/24401064/understanding-and-solving-the-diamond-problems-in-java
Anda perlu Java 8 untuk mendapatkan masalah pewarisan berganda, tetapi itu masih bukan masalah diamon seperti itu.
Seperti yang dikomentari JB Nizet, Anda dapat memperbaikinya dengan mengesampingkan saya.
Namun, Anda tidak memiliki masalah dengan itu
sumber
hi()
(untuk memperbaiki ambiguitas). Misalnya, dengan mengimplementasikannyaA.super.hi()
untuk memilih untuk mengimplementasikannya dengan cara yang sama dengan A.Sejauh menyangkut kompiler, kedua metode itu identik. Akan ada satu implementasi dari keduanya.
Ini bukan masalah jika kedua metode ini identik secara efektif, karena keduanya harus memiliki implementasi yang sama. Jika mereka berbeda secara kontraktual (sesuai dokumentasi untuk setiap antarmuka), Anda akan bermasalah.
sumber
Tidak ada yang bisa diidentifikasi. Antarmuka hanya melarang nama metode dan tanda tangan. Jika kedua antarmuka memiliki metode dengan nama dan tanda tangan yang persis sama, kelas pelaksana dapat mengimplementasikan kedua metode antarmuka dengan metode konkret tunggal.
Namun, jika kontrak semantik dari kedua metode antarmuka saling bertentangan, Anda telah kehilangan banyak hal; Anda tidak dapat mengimplementasikan kedua antarmuka dalam satu kelas saja.
sumber
Coba terapkan antarmuka sebagai anonim.
sumber
Seperti dalam antarmuka, kita hanya mendeklarasikan metode, kelas konkret yang mengimplementasikan kedua antarmuka ini mengerti bahwa hanya ada satu metode (seperti yang Anda jelaskan keduanya memiliki nama yang sama dalam tipe pengembalian). jadi seharusnya tidak ada masalah dengan itu. Anda akan dapat mendefinisikan metode itu di kelas beton.
Tetapi ketika dua antarmuka memiliki metode dengan nama yang sama tetapi jenis kembali berbeda dan Anda menerapkan dua metode di kelas beton:
Silakan lihat kode di bawah ini:
ketika kompiler mendapatkan metode "public void print ()" pertama kali terlihat di InterfaceA dan mendapatkannya. Tapi tetap saja itu memberikan kesalahan waktu kompilasi bahwa tipe pengembalian tidak kompatibel dengan metode InterfaceB.
Jadi itu menjadi rusak untuk kompiler.
Dengan cara ini, Anda tidak akan dapat mengimplementasikan dua antarmuka yang memiliki metode dengan nama yang sama tetapi tipe pengembalian yang berbeda.
sumber
Ya, jika keduanya sama, itu tidak masalah. Ini mengimplementasikan keduanya dengan metode beton tunggal per metode antarmuka.
sumber