Suatu hal yang aneh terjadi di Java ketika Anda menggunakan kelas abstrak untuk mengimplementasikan sebuah antarmuka: beberapa metode antarmuka bisa hilang sama sekali (yaitu tidak ada deklarasi abstrak atau implementasi aktual), tetapi kompilator tidak mengeluh.
Misalnya, antarmuka yang diberikan:
public interface IAnything {
void m1();
void m2();
void m3();
}
kelas abstrak berikut dikompilasi dengan riang tanpa peringatan atau kesalahan:
public abstract class AbstractThing implements IAnything {
public void m1() {}
public void m3() {}
}
Bisakah Anda menjelaskan mengapa?
java
interface
abstract-class
Giulio Piancastelli
sumber
sumber
:w
salah satu file.Jawaban:
Itu karena jika suatu kelas abstrak, maka menurut definisi Anda diminta untuk membuat subkelasnya untuk dibuat instance-nya. Subclass akan diminta (oleh compiler) untuk mengimplementasikan metode antarmuka apa pun yang ditinggalkan oleh class abstrak.
Mengikuti kode contoh Anda, coba buat subclass
AbstractThing
tanpa mengimplementasikanm2
metode dan lihat kesalahan apa yang diberikan compiler kepada Anda. Ini akan memaksa Anda untuk menerapkan metode ini.sumber
Sangat baik.
Anda tidak dapat membuat instance kelas abstrak .. tetapi kelas abstrak dapat digunakan untuk menampung implementasi umum untuk m1 () dan m3 ().
Jadi jika implementasi m2 () berbeda untuk setiap implementasi tetapi m1 dan m3 tidak. Anda dapat membuat berbagai implementasi beton yang berbeda hanya dengan implementasi m2 yang berbeda dan berasal dari AbstractThing - dengan menghormati prinsip DRY. Memvalidasi jika antarmuka diimplementasikan sepenuhnya untuk kelas abstrak adalah sia-sia ..
Pembaruan : Menariknya, saya menemukan bahwa C # memberlakukan ini sebagai kesalahan kompilasi. Anda dipaksa untuk menyalin tanda tangan metode dan mengawalnya dengan 'publik abstrak' di kelas dasar abstrak dalam skenario ini .. (sesuatu yang baru setiap hari :)
sumber
Tidak apa-apa. Untuk memahami hal di atas, Anda harus memahami hakikat kelas abstrak terlebih dahulu. Mereka mirip dengan antarmuka dalam hal itu. Inilah yang dikatakan Oracle tentang ini di sini .
Jadi, Anda harus memikirkan tentang apa yang terjadi ketika sebuah antarmuka memperluas antarmuka lain. Sebagai contoh ...
... seperti yang Anda lihat, ini juga dikompilasi dengan baik. Hanya karena, seperti kelas abstrak, sebuah antarmuka TIDAK dapat digunakan. Jadi, tidak perlu secara eksplisit menyebutkan metode dari "induknya". Namun, SEMUA tanda tangan metode induk DO secara implisit menjadi bagian dari antarmuka perluasan atau mengimplementasikan kelas abstrak. Jadi, sekali kelas yang tepat (yang bisa dipakai) memperluas di atas, itu AKAN diperlukan untuk memastikan bahwa setiap metode abstrak diimplementasikan.
Semoga membantu ... dan Allahu 'alam!
sumber
Interface berarti kelas yang tidak mengimplementasikan metodenya, tetapi hanya dengan deklarasi.
Di sisi lain, kelas abstrak adalah kelas yang dapat menerapkan beberapa metode bersama dengan beberapa metode hanya dengan deklarasi, tanpa implementasi.
Ketika kita mengimplementasikan sebuah antarmuka ke kelas abstrak, itu berarti kelas abstrak mewarisi semua metode antarmuka. Karena, tidak penting untuk mengimplementasikan semua metode dalam kelas abstrak namun ia datang ke kelas abstrak (dengan pewarisan juga), sehingga kelas abstrak dapat meninggalkan beberapa metode dalam antarmuka tanpa implementasi di sini. Tetapi, ketika kelas abstrak ini akan diwarisi oleh beberapa kelas konkret, mereka harus mengimplementasikan semua metode yang tidak diimplementasikan di kelas abstrak.
sumber
Diberikan antarmuka:
Beginilah sebenarnya Java melihatnya:
Jadi Anda dapat membiarkan beberapa (atau semua)
abstract
metode ini tidak diimplementasikan, seperti yang akan Anda lakukan dalam kasusabstract
kelas memperluasabstract
kelas lain .Bila Anda
implement
seoranginterface
, aturan bahwa semuainterface
metode harus dilaksanakan di berasalclass
, hanya berlaku untuk betonclass
pelaksanaan (yaitu, yang tidakabstract
sendiri).Jika Anda memang berencana untuk
abstract class
membuatnya, maka tidak ada aturan yang mengatakan Anda telah menggunakanimplement
semuainterface
metode (perhatikan bahwa dalam kasus seperti itu, wajib menyatakan turunanclass
sebagaiabstract
)sumber
javap IAnything.class
untuk menghasilkan cuplikan kode kedua.Referensi: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
sumber
Kelas abstrak tidak diperlukan untuk mengimplementasikan metode. Jadi meskipun itu mengimplementasikan sebuah antarmuka, metode abstrak dari antarmuka dapat tetap abstrak. Jika Anda mencoba mengimplementasikan antarmuka dalam kelas konkret (yaitu bukan abstrak) dan Anda tidak mengimplementasikan metode abstrak, kompilator akan memberi tahu Anda: Implementasikan metode abstrak atau deklarasikan kelas sebagai abstrak.
sumber