Haruskah kita meng-override implementasi metode antarmuka?

432

Haruskah metode yang mengimplementasikan metode antarmuka dijelaskan dengan @Override?

The javadoc dari Overridepenjelasan mengatakan:

Menunjukkan bahwa deklarasi metode dimaksudkan untuk mengganti deklarasi metode dalam superclass. Jika suatu metode dianotasi dengan tipe anotasi ini tetapi tidak mengesampingkan metode superclass, kompiler diperlukan untuk menghasilkan pesan kesalahan.

Saya tidak berpikir bahwa antarmuka secara teknis adalah superclass. Atau itu?

Question Elaboration

Benno Richters
sumber
5
wow pertanyaan ini bisa lebih pendek, tapi itu pertanyaan yang saya butuhkan. Terima kasih
Dan Rosenstark
1
Saya tidak dapat menemukan pengganti untuk artikel @Override (Oracle baru-baru ini memindahkan blog Sun). Apakah Anda tahu cara menemukannya?
Bill the Lizard
4
Kita harus memiliki anotasi @Implement sekarang (2015). Itu akan membuat semuanya menjadi jelas!
Alex
3
sekarang (2015) haruskah kita menggunakan @Override dengan java 8?
Lorenzo Sciuto

Jawaban:

305

Anda harus menggunakan @Override kapan pun memungkinkan. Itu mencegah kesalahan sederhana yang dibuat. Contoh:

class C {
    @Override
    public boolean equals(SomeClass obj){
        // code ...
    }
}

Ini tidak dikompilasi karena tidak menimpa dengan benar public boolean equals(Object obj).

Hal yang sama akan berlaku untuk metode yang mengimplementasikan antarmuka (hanya 1,6 ke atas ) atau mengganti metode kelas Super.

jjnguy
sumber
150
Perhatikan bahwa Anda tidak dapat menambahkan anotasi @Override ke metode yang mengimplementasikan antarmuka di Java 5 - itu menghasilkan kesalahan. Itu diizinkan di Jawa 6.
Bill Michell
17
Um, tidak, tidak. Bahkan, Eclipse memasukkan secara otomatis @Override saat mengisi metode yang mengimplementasikan antarmuka.
jjnguy
14
-1 hingga jawabannya mencakup penyebutan tentang perilaku yang berbeda dari Java 1.5 hingga 1.6 sehubungan dengan penerapan metode antarmuka. Hanya karena saya telah melihatnya menjadi aspek yang membingungkan bagi orang-orang dan itu benar-benar pantas disebutkan.
Grundlefleck
2
Jika eclipse mengeluh maka tingkatkan ur jdk ke> 1.5 dan ubah tingkat kepatuhan kompiler menjadi 1.6 atau 1.7. Untuk melakukan itu klik kanan pada ur project-> properties-> Java compiler dan pilih yang lebih tinggi dari 1,5.
Mawar
1
Adakah yang bisa memikirkan contoh yang benar-benar membenarkan jawaban (mengimplementasikan antarmuka daripada mengesampingkan metode dasar)? Nilai tambah yang besar bagi saya adalah membantu menentukan harapan pembaca tentang bagaimana dan dengan apa metode tertentu dapat digunakan.
Joe Lee-Moyet
103

Saya percaya bahwa perilaku javac telah berubah - dengan 1,5 itu melarang anotasi, dengan 1,6 tidak. Anotasi tersebut memberikan pemeriksaan waktu kompilasi ekstra, jadi jika Anda menggunakan 1,6, saya akan melakukannya.

Jon Skeet
sumber
1
Apa pemeriksaan tambahan?
Michael Carman
17
@Michael Anda dapat melihat apakah ada antarmuka yang dihapus.
Sanghyun Lee
68

Anda harus selalu membubuhi keterangan metode @Overridejika tersedia.

Dalam JDK 5 ini berarti metode overriding dari superclasses, dalam JDK 6, dan 7 itu berarti metode overriding dari superclasses, dan menerapkan metode antarmuka. Alasannya, seperti yang disebutkan sebelumnya, adalah memungkinkan kompiler untuk menangkap kesalahan di mana Anda pikir Anda mengganti (atau mengimplementasikan) metode, tetapi sebenarnya mendefinisikan metode baru (tanda tangan berbeda).

Contoh equals(Object)vs. equals(YourObject)adalah contoh standar, tetapi argumen yang sama dapat dibuat untuk implementasi antarmuka.

Saya membayangkan alasan mengapa tidak wajib menjelaskan metode implementasi antarmuka adalah bahwa JDK 5 menandai ini sebagai kesalahan kompilasi. Jika JDK 6 membuat anotasi ini wajib, itu akan merusak kompatibilitas.

Saya bukan pengguna Eclipse, tetapi di IDE lain (IntelliJ), @Overrideanotasi hanya ditambahkan ketika menerapkan metode antarmuka jika proyek ditetapkan sebagai proyek JDK 6+. Saya akan membayangkan bahwa Eclipse serupa.

Namun, saya lebih suka melihat anotasi yang berbeda untuk penggunaan ini, mungkin @Implementsanotasi.

GKelly
sumber
11

JDK 5.0 tidak memungkinkan Anda untuk menggunakan @Overrideanotasi jika Anda menerapkan metode yang dinyatakan dalam antarmuka (kesalahan kompilasi), tetapi JDK 6.0 memungkinkannya. Jadi mungkin Anda dapat mengkonfigurasi preferensi proyek Anda sesuai dengan kebutuhan Anda.

Prajurit Diam
sumber
4

Jika kelas konkret tidak menimpa metode abstrak, menggunakan @Overrideuntuk implementasi adalah hal yang terbuka karena kompiler akan selalu memperingatkan Anda tentang metode yang tidak diimplementasikan. Dalam kasus ini, dapat dibuat argumen yang mengurangi keterbacaan - lebih banyak hal dibaca pada kode Anda dan, pada tingkat yang lebih rendah, disebut @Overridedan tidak @Implement.

juanchito
sumber
3

Mengganti metode Anda sendiri yang diwarisi dari kelas Anda sendiri biasanya tidak akan berhenti pada refactorings menggunakan ide. Tetapi jika Anda mengganti metode yang diwarisi dari perpustakaan, disarankan untuk menggunakannya. Jika tidak, Anda sering tidak mendapatkan kesalahan pada perubahan pustaka nanti, tetapi bug yang tersembunyi dengan baik.

Arne Burmeister
sumber
3

Ini bukan masalah dengan JDK. Dalam Eclipse Helios, ini memungkinkan anotasi @Override untuk metode antarmuka yang diterapkan, mana pun JDK 5 atau 6. Sedangkan untuk Eclipse Galileo, anotasi @Override tidak diperbolehkan, mana pun JDK 5 atau 6.

lwpro2
sumber
2

Bagi saya, sering kali ini adalah satu-satunya alasan beberapa kode memerlukan Java 6 untuk dikompilasi. Tidak yakin apakah itu layak.

Fabian Steeg
sumber
2

Dengan membaca javadoc di java8, Anda dapat menemukan yang berikut di deklarasi antarmuka Override:

Jika suatu metode dijelaskan dengan kompiler jenis penjelasan ini diperlukan untuk menghasilkan pesan kesalahan kecuali setidaknya salah satu dari kondisi berikut ini berlaku:

  • Metode tidak mengesampingkan atau menerapkan metode yang dinyatakan dalam supertype.
  • Metode ini memiliki tanda tangan yang menimpa-setara dengan metode publik apa pun yang dinyatakan dalam {@linkplain Object}.

Jadi, setidaknya di java8, Anda harus menggunakan @Override pada implementasi metode antarmuka.

Zhao Pengfei
sumber
1

Eclipse sendiri akan menambahkan @Overrideanotasi ketika Anda mengatakannya untuk "menghasilkan metode yang tidak diimplementasikan" selama pembuatan kelas yang mengimplementasikan antarmuka.

savetheclocktower
sumber
1

Masalah dengan menyertakan @Overrideadalah bahwa hal itu membuat Anda berpikir bahwa Anda lupa memanggil super.theOverridenMethod()metode, yang sangat membingungkan . Ini harus sebening kristal. Mungkin Java harus menawarkan @Interfaceuntuk digunakan di sini. Oh well, kekhasan Jawa setengah-setengah ...

spujia
sumber
3
Memanggil super, saat tidak mengimplementasikan antarmuka, bukanlah sesuatu yang selalu perlu atau ingin Anda lakukan. Terkadang, Anda menambahkan fungsionalitas - begitu Anda menyebutnya. Di lain waktu, Anda mengganti fungsionalitas, jadi Anda tidak menyebutnya. Seorang penulis API harus mendokumentasikan apakah itu bergantung pada fungsi internal atau tidak dan membuat kontrak yang terdokumentasi tentang bagaimana kelas dapat diperluas dengan benar.
lilbyrdie
1

Di java 6 dan versi yang lebih baru, Anda bisa menggunakan @Overridemetode yang mengimplementasikan antarmuka.

Tapi, saya tidak berpikir itu masuk akal: menimpa berarti Anda memiliki metode di kelas super, dan Anda menerapkannya di sub kelas.

Jika Anda mengimplementasikan antarmuka, saya pikir kita harus menggunakan @Implementatau sesuatu yang lain, tetapi tidak @Override.

ZhaoGang
sumber
0

Untuk antarmuka, menggunakan @Override menyebabkan kesalahan kompilasi. Jadi, saya harus menghapusnya.

Pesan kesalahan masuk " The method getAllProducts() of type InMemoryProductRepository must override a superclass method".

Itu juga membaca " One quick fix available: Remove @Override annotation."

Itu di Eclipse 4.6.3, JDK 1.8.0_144.

Park JongBum
sumber
0

Jika kelas yang mengimplementasikannya interfaceadalah abstractkelas, @Overrideberguna untuk memastikan bahwa implementasi adalah untuk suatu interfacemetode; tanpa @Overridesuatu abstractkelas hanya akan mengkompilasi denda bahkan jika tanda tangan metode implementasi tidak cocok dengan metode yang dinyatakan dalam interface; interfacemetode yang tidak cocok akan tetap tidak diterapkan. Dokumen Java dikutip oleh @Zhao

Metode tidak mengesampingkan atau menerapkan metode yang dinyatakan dalam supertype

jelas mengacu pada abstractkelas super; sebuah interfacetidak bisa disebut supertype. Jadi, @Overrideitu berlebihan dan tidak masuk akal untuk interfaceimplementasi metode di kelas konkret.

Madhu
sumber