Antarmuka abstrak Java

197

Pertimbangkan contoh (yang mengkompilasi di java)

public abstract interface Interface {
    public void interfacing();
    public abstract boolean interfacing(boolean really);
}

Mengapa antarmuka harus "dinyatakan" abstrak? Apakah ada aturan lain yang berlaku dengan antarmuka abstrak?


Akhirnya: Jika abstractusang, mengapa itu dimasukkan di Jawa? Apakah ada riwayat untuk antarmuka abstrak?

Buhake Sindi
sumber
5
Bukan duplikat mengingat bagian " Akhirnya: .... ".
aioobe
Pertanyaan terkait ini mengutip contoh nyata: stackoverflow.com/questions/4380796/…
Raedwald
1
Dan mengapa Eclipse menambahkan 'abstrak' secara default saat Anda 'mengekstrak antarmuka'?
ModdyFire
@ModdyFire, tolong jelaskan?
Buhake Sindi

Jawaban:

447

Mengapa antarmuka harus "dinyatakan" abstrak?

Ini bukan.

public abstract interface Interface {
       \___.__/
           |
           '----> Neither this...

    public void interfacing();
    public abstract boolean interfacing(boolean really);
           \___.__/
               |
               '----> nor this, are necessary.
}

Antarmuka dan metode mereka secara implisit abstractdan menambahkan bahwa pengubah tidak ada bedanya.

Apakah ada aturan lain yang berlaku dengan antarmuka abstrak?

Tidak, aturan yang sama berlaku. Metode harus diterapkan oleh kelas pelaksana (konkret) apa pun.

Jika abstrak sudah usang, mengapa abstrak dimasukkan di Jawa? Apakah ada riwayat untuk antarmuka abstrak?

Pertanyaan menarik. Saya menggali edisi pertama JLS, dan bahkan di sana tertulis "Pengubah ini sudah usang dan tidak boleh digunakan dalam program Java baru" .

Oke, menggali lebih jauh ... Setelah mengenai banyak tautan yang rusak, saya berhasil menemukan salinan Spesifikasi Oak 0.2 asli (atau "manual"). Cukup menarik, harus saya katakan, dan hanya 38 halaman secara total! :-)

Di bawah Bagian 5, Antarmuka, ini memberikan contoh berikut:

public interface Storing {
    void freezeDry(Stream s) = 0;
    void reconstitute(Stream s) = 0;
}

Dan di margin katanya

Di masa mendatang, bagian "= 0" dari metode mendeklarasikan dalam antarmuka mungkin hilang.

Dengan asumsi =0digantikan oleh abstractkata kunci, saya menduga abstractitu pada beberapa titik wajib untuk metode antarmuka!


Artikel terkait: Java: Antarmuka abstrak dan metode antarmuka abstrak

aioobe
sumber
3
tetapi abstrak itu sendiri tidak usang, atau? Itu sudah usang untuk antarmuka tetapi masih ada kelas dan metode abstrak.
user85421
Terima kasih ;-) Saya pikir saya akhirnya menemukan asal untuk bahkan memungkinkan abstractdi depan metode antarmuka.
aioobe
13
Wow. Jadi sudah usang "dengan desain". Para perancang JLS itu benar-benar selalu takut untuk menghancurkan sesuatu, bahkan memecahkan hal-hal yang tidak pernah dirilis ... :-)
Lukas Eder
@aioobe, Anda harus menjadi crawler web Google yang kami tidak tahu tentang ... lol
Buhake Sindi
18
Btw. "publik" juga tidak diperlukan pada metode dalam deklarasi antarmuka ... mereka selalu bersifat publik.
rec
37

Itu tidak perlu, itu opsional, seperti publicpada metode antarmuka.

Lihat JLS tentang ini:

http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html

9.1.1.1 Antarmuka abstrak Setiap antarmuka secara abstrak tersirat. Pengubah ini sudah usang dan tidak boleh digunakan dalam program baru.

Dan

9.4 Deklarasi Metode Abstrak

[...]

Untuk kompatibilitas dengan versi Java platform yang lebih lama, ini diperbolehkan tetapi tidak dianjurkan, karena gaya, untuk secara berlebihan menentukan pengubah abstrak untuk metode yang dideklarasikan dalam antarmuka.

Hal ini diizinkan, tetapi sangat tidak disarankan karena masalah gaya, untuk secara spesifik menentukan pengubah publik untuk metode antarmuka.

Lukas Eder
sumber
7
ke JLS: Diijinkan, tetapi sangat tidak disarankan, sebagai gaya, untuk secara berlebihan menulis dua kalimat dengan makna yang sama dan kata-kata yang hampir persis bersebelahan satu sama lain ...
n611x007
11

Tidak perlu mendeklarasikan abstrak antarmuka.

Sama seperti mendeklarasikan semua metode publik (yang sudah ada jika antarmuka publik) atau abstrak (yang sudah ada dalam antarmuka) berlebihan.

Tidak ada yang menghentikan Anda.

Hal-hal lain yang dapat Anda nyatakan secara eksplisit, tetapi tidak perlu:

  • panggil super () di baris pertama konstruktor
  • extends Object
  • mengimplementasikan antarmuka yang diwarisi

Apakah ada aturan lain yang berlaku dengan antarmuka abstrak?

Antarmuka sudah "abstrak". Menerapkan kembali kata kunci itu sama sekali tidak membuat perbedaan.

Thilo
sumber
2
Tampaknya, metodenya bahkan publik jika antarmuka itu sendiri adalah paket-pribadi.
Thilo
7

Ketahuilah bahwa di Spring ini memiliki makna non akademik. Antarmuka abstrak adalah peringatan bagi pengembang untuk tidak menggunakannya @Autowired. Saya berharap bahwa musim semi / gerhana @Autowiredakan melihat atribut ini dan memperingatkan / gagal tentang penggunaan seperti itu.

Contoh nyata: @Service proxy di bawah @Transnational ke @Repository perlu menggunakan metode dasar yang sama namun mereka harus menggunakan antarmuka berbeda yang memperpanjang antarmuka abstrak ini karena @Autowired. (Saya sebut antarmuka XXXSpec ini)

Adi Lev
sumber
+1 hit yang bagus, saya mencari secara luas untuk pemisahan injeksi sessionbean non-pasif. Mungkin saya bisa menggunakan findbugs / checkstyle untuk suatu peraturan ....
Grim
2

Itu tidak perlu. Ini adalah kekhasan bahasa.

Bohemian
sumber
2

Itu tidak perlu, karena antarmuka secara abstrak abstrak karena semua metode dalam antarmuka abstrak.

Swagatika
sumber
-2

Antarmuka abstrak tidak redundan seperti yang dikatakan semua orang, setidaknya secara teori.

Antarmuka dapat diperluas, seperti halnya Kelas. Jika Anda mendesain hierarki Antarmuka untuk aplikasi Anda, Anda mungkin memiliki Antarmuka 'Basis', Anda memperluas dari Antarmuka lain dari tetapi tidak ingin sebagai Obyek itu sendiri.

Contoh:

public abstract interface MyBaseInterface {
    public String getName();
}

public interface MyBoat extends MyBaseInterface {
    public String getMastSize();
}

public interface MyDog extends MyBaseInterface {
    public long tinsOfFoodPerDay();
}

Anda tidak ingin Kelas mengimplementasikan MyBaseInterface, hanya dua yang lain, MMyDog dan MyBoat, tetapi kedua antarmuka berbagi antarmuka MyBaseInterface, jadi miliki properti 'nama'.

Saya tahu ini agak akademis, tetapi saya pikir beberapa orang mungkin menganggapnya menarik. :-)

Ini benar-benar hanya 'penanda' dalam hal ini, untuk memberi sinyal kepada implementator dari antarmuka yang tidak dirancang untuk diimplementasikan sendiri. Saya harus menunjukkan kompiler (Setidaknya matahari / ora 1.6 saya mencobanya dengan) mengkompilasi kelas yang mengimplementasikan antarmuka abstrak.

Eurospoofer
sumber
3
Saya yakin Anda benar-benar salah mengerti pertanyaan saya.
Buhake Sindi
3
Saya tidak setuju dengan alasan ini. Saya pikir setiap antarmuka harus menyediakan set fungsi yang dapat digunakan sepenuhnya dan oleh karena itu setiap antarmuka dapat diimplementasikan dengan sendirinya. Juga tidak akan ada alasan bagi seorang kompiler untuk menolak mengkompilasi kelas yang mengimplementasikan antarmuka yang dinyatakan secara eksplisit sebagai abstrak, karena semua antarmuka sudah abstrak secara implisit. Itu akan mengubah arti kata kunci "abstrak" sepenuhnya.
BladeCoder
-3

Nah 'Antarmuka Abstrak' adalah konstruksi Leksikal: http://en.wikipedia.org/wiki/Lexical_analysis .

Diperlukan oleh kompiler, Anda juga bisa menulis interface.

Yah jangan terlalu banyak ke konstruksi Lexical bahasa karena mereka mungkin telah meletakkannya di sana untuk menyelesaikan beberapa ambiguitas kompilasi yang disebut sebagai kasus khusus selama proses kompilasi atau untuk beberapa kompatibilitas mundur, cobalah untuk fokus pada konstruksi Lexical inti.

Inti dari `antarmuka adalah untuk menangkap beberapa konsep abstrak (ide / pemikiran / pemikiran tingkat tinggi dll) yang implementasinya dapat bervariasi ... yaitu, mungkin ada beberapa implementasi.

Antarmuka adalah tipe data abstrak murni yang mewakili fitur Objek yang ditangkap atau diwakilinya.

Fitur dapat direpresentasikan oleh ruang atau waktu. Ketika mereka diwakili oleh ruang (penyimpanan memori) itu berarti bahwa kelas beton Anda akan mengimplementasikan bidang dan metode / metode yang akan beroperasi di bidang itu atau berdasarkan waktu yang berarti bahwa tugas mengimplementasikan fitur adalah murni komputasi (memerlukan lebih banyak jam cpu untuk diproses) sehingga Anda memiliki trade off antara ruang dan waktu untuk implementasi fitur.

Jika kelas konkret Anda tidak mengimplementasikan semua fitur itu lagi menjadi abstrak karena Anda memiliki implementasi pemikiran atau ide atau abstrak Anda tetapi tidak lengkap, Anda tentukan berdasarkan abstractkelas.

Kelas konkret akan menjadi kelas / set kelas yang akan sepenuhnya menangkap abstrak yang Anda coba untuk menangkap kelas XYZ.

Jadi polanya

Interface--->Abstract class/Abstract classes(depends)-->Concrete class
Manish
sumber
1
Jawaban ini sama sekali tidak menjawab pertanyaan saya. Juga "It seams like you are new to Java. Betulkah?
Buhake Sindi
"abstrak sudah usang"
Manish
(1) "abstrak sudah usang" -> jika mereka menghapusnya dan kompiler berhenti mengenalinya maka versi sebelumnya dari kode sumber menggunakan "antarmuka abstrak" tidak dapat dikompilasi dalam versi yang lebih baru .. Mereka perlu mempertahankan kompatibilitas ke belakang. Ketika Anda mendefinisikan antarmuka abstrak arti kata kunci antarmuka terjebak bersama dengan itu "abstrak" yang merupakan versi yang jauh lebih bersih namun untuk programmer berpengalaman seperti Anda mereka menyediakan "antarmuka" pintas .. pertanyaan Anda mirip dengan i = i + 1 == > i ++ .. pilihan ada di tangan Anda: D
Manish
Lihatlah jawaban yang diterima. Saya tahu abstractantarmuka sudah usang. Saya ingin tahu mengapa masih bisa diterima dan apa sejarah di balik abstractantarmuka. Anda memberi saya panduan Java 101 tentang antarmuka abstrak vs.
Buhake Sindi
Ini bukan konstruksi leksikal. Itu adalah sintaks. Secara semantik itu mubazir. Itu tidak 'diperlukan oleh kompiler'. Bagian tentang ruang / waktu hanyalah omong kosong. Tak satu pun dari omong kosong ini menjawab pertanyaan yang diajukan. Jangan gunakan pemformatan kode untuk teks yang bukan kode.
Marquis of Lorne