Saya diberi pertanyaan, saya ingin jawaban saya ditinjau di sini.
T: Dalam skenario mana lebih tepat untuk memperluas kelas abstrak daripada mengimplementasikan antarmuka?
A: Jika kami menggunakan pola desain metode template.
Apakah saya benar ?
Saya minta maaf jika saya tidak dapat menyatakan pertanyaan dengan jelas.
Saya tahu perbedaan mendasar antara kelas abstrak dan antarmuka.
1) gunakan kelas abstrak ketika persyaratannya sedemikian rupa sehingga kita perlu mengimplementasikan fungsionalitas yang sama di setiap subkelas untuk operasi tertentu (mengimplementasikan metode) dan fungsionalitas yang berbeda untuk beberapa operasi lain (hanya tanda tangan metode)
2) gunakan antarmuka jika Anda perlu meletakkan tanda tangan yang sama (dan implementasi yang berbeda) sehingga Anda dapat mematuhi implementasi antarmuka
3) kita dapat memperluas maksimal satu kelas abstrak, tetapi dapat mengimplementasikan lebih dari satu antarmuka
Mengulangi pertanyaan: Apakah ada skenario lain, selain yang disebutkan di atas, di mana secara khusus kita perlu menggunakan kelas abstrak (salah satunya adalah lihat apakah pola desain metode template secara konseptual hanya didasarkan pada ini)?
Antarmuka vs. kelas Abstrak
Memilih di antara keduanya sangat bergantung pada apa yang ingin Anda lakukan, tetapi untungnya bagi kami, Erich Gamma dapat sedikit membantu kami.
Seperti biasa, ada trade-off, antarmuka memberi Anda kebebasan berkenaan dengan kelas dasar, kelas abstrak memberi Anda kebebasan untuk menambahkan metode baru nanti . - Erich Gamma
Anda tidak dapat pergi dan mengubah Antarmuka tanpa harus mengubah banyak hal lain dalam kode Anda, jadi satu-satunya cara untuk menghindarinya adalah dengan membuat Antarmuka baru, yang mungkin tidak selalu merupakan hal yang baik.
Abstract classes
sebaiknya digunakan untuk objek yang terkait erat. Interfaces
lebih baik dalam menyediakan fungsionalitas umum untuk kelas yang tidak terkait.
sumber
Jawaban:
Kapan Menggunakan Antarmuka
Antarmuka memungkinkan seseorang untuk memulai dari awal untuk mengimplementasikan antarmuka Anda atau mengimplementasikan antarmuka Anda dalam beberapa kode lain yang tujuan asli atau utamanya sangat berbeda dari antarmuka Anda. Bagi mereka, antarmuka Anda hanyalah insidental, sesuatu yang harus ditambahkan ke kode mereka untuk dapat menggunakan paket Anda. Kerugiannya adalah setiap metode di antarmuka harus bersifat publik. Anda mungkin tidak ingin membeberkan semuanya.
Kapan Menggunakan kelas Abstrak
Kelas abstrak, sebaliknya, menyediakan lebih banyak struktur. Biasanya mendefinisikan beberapa implementasi default dan menyediakan beberapa alat yang berguna untuk implementasi penuh. Tangkapannya adalah, kode yang menggunakannya harus menggunakan kelas Anda sebagai basis. Itu mungkin sangat merepotkan jika programmer lain yang ingin menggunakan paket Anda telah mengembangkan hierarki kelas mereka sendiri secara mandiri. Di Java, sebuah kelas hanya dapat mewarisi dari satu kelas dasar.
Kapan Menggunakan Keduanya
Anda dapat menawarkan yang terbaik dari kedua dunia, antarmuka, dan kelas abstrak. Pelaksana dapat mengabaikan kelas abstrak Anda jika mereka memilih. Satu-satunya kelemahan melakukan itu adalah memanggil metode melalui nama antarmuka mereka sedikit lebih lambat daripada memanggilnya melalui nama kelas abstrak mereka.
sumber
If we are using template method design pattern
Kami tidak bisa mengatakanYES
atauNO
Ya, jika Anda menggunakan JAXB. Itu tidak suka antarmuka. Anda sebaiknya menggunakan kelas abstrak atau mengatasi batasan ini dengan obat generik.
Dari postingan blog pribadi :
Antarmuka:
Secara umum, antarmuka harus digunakan untuk mendefinisikan kontrak (apa yang ingin dicapai, bukan bagaimana mencapainya).
Kelas Abstrak:
Kelas abstrak harus digunakan untuk implementasi (parsial). Mereka bisa menjadi sarana untuk menahan cara kontrak API harus diterapkan.
sumber
default
danstatic
metode juga.Antarmuka digunakan ketika Anda memiliki skenario bahwa semua kelas memiliki struktur yang sama tetapi memiliki fungsionalitas yang sama sekali berbeda.
Kelas abstrak digunakan ketika Anda memiliki skenario bahwa semua kelas memiliki struktur yang sama tetapi beberapa fungsi yang sama dan beberapa berbeda.
Lihat artikelnya: http://shoaibmk.blogspot.com/2011/09/abstract-class-is-class-which-cannot-be.html
sumber
Ada banyak jawaban bagus di sini, tetapi saya sering menemukan menggunakan KEDUA antarmuka dan kelas abstrak adalah rute terbaik. Pertimbangkan contoh yang dibuat-buat ini:
Anda adalah pengembang perangkat lunak di bank investasi, dan perlu membangun sistem yang menempatkan pesanan ke pasar. Antarmuka Anda menangkap gagasan paling umum tentang apa yang dilakukan sistem perdagangan ,
1) Trading system places orders 2) Trading system receives acknowledgements
dan dapat ditangkap dalam sebuah antarmuka,
ITradeSystem
public interface ITradeSystem{ public void placeOrder(IOrder order); public void ackOrder(IOrder order); }
Sekarang teknisi yang bekerja di meja penjualan dan di sepanjang lini bisnis lainnya dapat mulai berinteraksi dengan sistem Anda untuk menambahkan fungsionalitas penempatan pesanan ke aplikasi mereka yang ada. Dan Anda bahkan belum mulai membangun! Inilah kekuatan antarmuka.
Jadi Anda melanjutkan dan membangun sistem untuk pedagang saham ; mereka telah mendengar bahwa sistem Anda memiliki fitur untuk menemukan saham murah dan sangat ingin mencobanya! Anda menangkap perilaku ini dalam sebuah metode yang disebut
findGoodDeals()
, tetapi juga menyadari ada banyak hal berantakan yang terlibat dalam menghubungkan ke pasar. Misalnya, Anda harus membukaSocketChannel
,public class StockTradeSystem implements ITradeSystem{ @Override public void placeOrder(IOrder order); getMarket().place(order); @Override public void ackOrder(IOrder order); System.out.println("Order received" + order); private void connectToMarket(); SocketChannel sock = Socket.open(); sock.bind(marketAddress); <LOTS MORE MESSY CODE> } public void findGoodDeals(); deals = <apply magic wizardry> System.out.println("The best stocks to buy are: " + deals); }
Implementasi konkret akan memiliki banyak metode berantakan seperti ini
connectToMarket()
, tetapifindGoodDeals()
semua pedagang benar-benar peduli.Sekarang di sinilah kelas abstrak berperan. Bos Anda memberi tahu Anda bahwa pedagang mata uang juga ingin menggunakan sistem Anda. Dan melihat pasar mata uang, Anda melihat pipa ledeng hampir identik dengan pasar saham. Bahkan,
connectToMarket()
dapat digunakan kembali secara verbatim untuk menghubungkan ke pasar valuta asing. Namun,findGoodDeals()
adalah konsep yang jauh berbeda di arena mata uang. Jadi sebelum Anda memberikan basis kode kepada anak ahli valuta asing di seberang lautan, Anda terlebih dahulu melakukan refaktorisasi ke dalam sebuahabstract
kelas, meninggalkanfindGoodDeals()
public abstract class ABCTradeSystem implements ITradeSystem{ public abstract void findGoodDeals(); @Override public void placeOrder(IOrder order); getMarket().place(order); @Override public void ackOrder(IOrder order); System.out.println("Order received" + order); private void connectToMarket(); SocketChannel sock = Socket.open(); sock.bind(marketAddress); <LOTS MORE MESSY CODE> }
Sistem perdagangan saham Anda menerapkan
findGoodDeals()
seperti yang telah Anda tentukan,public class StockTradeSystem extends ABCTradeSystem{ public void findGoodDeals(); deals = <apply magic wizardry> System.out.println("The best stocks to buy are: " + deals); }
tetapi sekarang bocah ahli FX dapat membangun sistemnya hanya dengan menyediakan implementasi
findGoodDeals()
untuk mata uang; dia tidak harus menerapkan ulang koneksi soket atau bahkan metode antarmuka!public class CurrencyTradeSystem extends ABCTradeSystem{ public void findGoodDeals(); ccys = <Genius stuff to find undervalued currencies> System.out.println("The best FX spot rates are: " + ccys); }
Pemrograman ke antarmuka sangat bermanfaat, tetapi aplikasi serupa sering kali menerapkan ulang metode dengan cara yang hampir identik. Menggunakan kelas abstrak menghindari reimplmentation, sambil mempertahankan kekuatan antarmuka.
Catatan: orang mungkin bertanya-tanya mengapa
findGreatDeals()
bukan bagian dari antarmuka. Ingat, antarmuka menentukan komponen paling umum dari sistem perdagangan. Insinyur lain mungkin mengembangkan sistem perdagangan yang BENAR-BENAR BERBEDA, di mana mereka tidak peduli tentang menemukan penawaran yang bagus. Antarmuka tersebut menjamin bahwa meja penjualan juga dapat berinteraksi dengan sistem mereka, jadi sebaiknya tidak melibatkan antarmuka Anda dengan konsep aplikasi seperti "penawaran hebat".sumber
Mana yang harus Anda gunakan, kelas atau antarmuka abstrak?
Pertimbangkan untuk menggunakan kelas abstrak jika salah satu dari pernyataan berikut berlaku untuk kasus penggunaan Anda:
Anda ingin berbagi kode di antara beberapa kelas yang terkait erat.
Anda berharap bahwa kelas yang memperluas kelas abstrak Anda memiliki banyak metode atau bidang umum, atau memerlukan pengubah akses selain publik (seperti dilindungi dan pribadi).
Anda ingin mendeklarasikan bidang non-statis atau non-final. Ini memungkinkan Anda untuk menentukan metode yang dapat mengakses dan mengubah status objek tempat mereka berada.
Pertimbangkan untuk menggunakan antarmuka jika salah satu dari pernyataan ini berlaku untuk kasus penggunaan Anda:
Anda berharap bahwa kelas yang tidak terkait akan mengimplementasikan antarmuka Anda. Misalnya, antarmuka Comparable dan Cloneable diimplementasikan oleh banyak kelas yang tidak terkait.
Anda ingin menentukan perilaku tipe data tertentu, tetapi tidak peduli tentang siapa yang mengimplementasikan perilakunya.
Anda ingin memanfaatkan multiple inheritance of type.
http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
sumber
Banyak hal telah banyak berubah dalam tiga tahun terakhir dengan penambahan kemampuan baru untuk antarmuka dengan rilis Java 8.
Dari halaman dokumentasi oracle di antarmuka:
Seperti yang Anda kutip dalam pertanyaan Anda, kelas abstrak paling cocok untuk pola metode templat di mana Anda harus membuat kerangka. Antarmuka tidak dapat digunakan di sini.
Satu lagi pertimbangan untuk lebih memilih kelas abstrak daripada antarmuka:
Anda tidak memiliki implementasi di kelas dasar dan hanya sub-kelas yang harus menentukan implementasinya sendiri. Anda memerlukan kelas abstrak sebagai ganti antarmuka karena Anda ingin berbagi status dengan sub-kelas.
Kelas abstrak menetapkan "adalah" hubungan antara kelas terkait dan antarmuka menyediakan "memiliki" kemampuan antara kelas yang tidak terkait .
Mengenai bagian kedua dari pertanyaan Anda, yang valid untuk sebagian besar bahasa pemrograman termasuk java sebelum rilis java-8
Jika Anda lebih suka kelas abstrak untuk antarmuka sebelumnya dengan dua pertimbangan di atas, Anda harus berpikir ulang sekarang karena metode default telah menambahkan kemampuan yang kuat ke antarmuka.
Untuk memilih salah satunya antara antarmuka dan kelas abstrak, halaman dokumentasi oracle mengutip yang:
Lihat pertanyaan terkait ini untuk detail lebih lanjut:
Antarmuka vs Kelas Abstrak (OO umum)
Bagaimana seharusnya saya menjelaskan perbedaan antara Antarmuka dan kelas Abstrak?
Singkatnya: Saldo sekarang lebih condong ke antarmuka .
Beberapa pola desain menggunakan kelas abstrak (melalui antarmuka) selain dari pola metode Template.
Pola penciptaan:
Abstract_factory_pattern
Pola struktural:
Decorator_pattern
Pola perilaku:
Mediator_pattern
sumber
Anda tidak benar. Ada banyak skenario. Tidak mungkin untuk menguranginya menjadi satu aturan 8 kata.
sumber
Jawaban terpendeknya adalah, perluas kelas abstrak ketika beberapa fungsi yang Anda cari sudah diterapkan di dalamnya.
Jika Anda mengimplementasikan antarmuka Anda harus mengimplementasikan semua metode. Tetapi untuk kelas abstrak jumlah metode yang perlu Anda implementasikan mungkin lebih sedikit.
Dalam pola desain template harus ada perilaku yang ditentukan. Perilaku ini bergantung pada metode lain yang abstrak. Dengan membuat sub kelas dan mendefinisikan metode-metode tersebut Anda benar-benar mendefinisikan perilaku utama. Perilaku yang mendasari tidak dapat berada di antarmuka karena antarmuka tidak mendefinisikan apa pun, hanya mendeklarasikan. Jadi pola desain template selalu hadir dengan kelas abstrak. Jika Anda ingin menjaga alur perilaku tetap utuh, Anda harus memperluas kelas abstrak tetapi tidak mengganti perilaku utama.
sumber
Pure virtual functions can also be used where the method declarations are being used to define an interface - similar to what the interface keyword in Java explicitly specifies. In such a use, derived classes will supply all implementations. In such a design pattern, the abstract class which serves as an interface will contain only pure virtual functions, but no data members or ordinary methods.
Bagian (1/2)no data members or ordinary methods
[dalam Kelas Abstrak].Menurut saya, perbedaan dasarnya adalah itu
an interface can't contain non abstract methods while an abstract class can
. Jadi jika subclass berbagi perilaku yang sama, perilaku ini dapat diimplementasikan di super class dan dengan demikian diwarisi di subclassJuga saya kutip yang berikut dari buku "desain arsitektur perangkat lunak ppatterns di java"
"Dalam bahasa pemrograman Java, tidak ada dukungan untuk multiple inheritance. Artinya sebuah kelas hanya dapat mewarisi dari satu kelas tunggal. Oleh karena itu, pewarisan harus digunakan hanya jika benar-benar diperlukan. Jika memungkinkan, metode yang menunjukkan perilaku umum harus dideklarasikan dalam bentuk antarmuka Java untuk diimplementasikan oleh kelas pelaksana yang berbeda. Namun antarmuka mengalami keterbatasan sehingga mereka tidak dapat menyediakan implementasi metode. Ini berarti bahwa setiap pelaksana antarmuka harus secara eksplisit mengimplementasikan semua metode yang dideklarasikan dalam sebuah antarmuka, bahkan ketika beberapa di antaranya metode mewakili bagian yang tidak berubah dari fungsionalitas dan memiliki implementasi yang persis sama di semua kelas pelaksana. Hal ini mengarah ke kode yang berlebihan.Contoh berikut menunjukkan bagaimana pola Abstrak Parent Class dapat digunakan dalam kasus seperti itu tanpa memerlukan implementasi metode yang berlebihan. "
sumber
Kelas abstrak berbeda dari antarmuka dalam dua aspek penting
sumber
Ini adalah pertanyaan yang bagus. Keduanya tidak sama tetapi dapat digunakan untuk beberapa alasan yang sama, seperti menulis ulang. Saat membuatnya, yang terbaik adalah menggunakan Antarmuka. Ketika turun ke kelas, itu bagus untuk debugging.
sumber
Abstract classes should be extended when you want to some common behavior to get extended
. Kelas super Abstrak akan memiliki perilaku yang sama dan akan menentukan metode abstrak / perilaku spesifik yang harus diterapkan oleh sub kelas.Interfaces allows you to change the implementation anytime allowing the interface to be intact
.sumber
Ini pemahaman saya, semoga ini membantu
Kelas abstrak:
Antarmuka:
sumber
Penggunaan abstrak dan antarmuka:
Satu memiliki "Hubungan-Is-A" dan yang lainnya memiliki "Hubungan-Has-A"
Properti default telah diatur dalam abstrak dan properti tambahan dapat diekspresikan melalui antarmuka.
Contoh: -> Dalam diri manusia kita memiliki beberapa properti default yaitu makan, tidur, dll. Tetapi jika ada yang memiliki aktivitas kurikuler lain seperti berenang, bermain, dll, itu dapat diekspresikan oleh Interface.
sumber