Apa perbedaan antara fungsi abstrak dan fungsi virtual? Dalam kasus apa disarankan menggunakan virtual atau abstrak? Mana yang merupakan pendekatan terbaik?
oop
programming-languages
abstract
virtual-functions
Moran Helman
sumber
sumber
Jawaban:
Fungsi abstrak tidak dapat memiliki fungsionalitas. Anda pada dasarnya mengatakan, setiap kelas anak HARUS memberikan versi mereka sendiri dari metode ini, namun terlalu umum untuk mencoba menerapkannya di kelas induk.
Fungsi virtual , pada dasarnya mengatakan tampilan, inilah fungsionalitas yang mungkin atau mungkin tidak cukup baik untuk kelas anak. Jadi jika itu cukup baik, gunakan metode ini, jika tidak, maka timpa saya, dan berikan fungsionalitas Anda sendiri.
sumber
Fungsi abstrak tidak memiliki implementasi dan hanya dapat dideklarasikan pada kelas abstrak. Ini memaksa kelas turunan untuk menyediakan implementasi.
Fungsi virtual menyediakan implementasi default dan bisa ada di kelas abstrak atau kelas non-abstrak.
Jadi misalnya:
sumber
MyBase
kelas Anda harus mengimplementasikan kelas abstrak , entah bagaimana? Saya tidak sering melakukan ini, sehingga saya bisa salah. Saya tidak melihat itu dalam contoh Anda.abstract
kelas yang dapat memilikiabstract
anggota.abstract
kelas yang mewarisi dariabstract
kelas keharusanoverride
nyaabstract
anggota.abstract
anggota secara implisitvirtual
.abstract
anggota tidak dapat memberikan implementasi apa pun (abstract
disebutpure virtual
dalam beberapa bahasa).sumber
virtual
atau tidakvirtual
. Seorangabstract
anggota (yaitu properti abstrak, metode abstrak) sama seperti metode virtual, yaitu Anda dapat menimpanya, kecuali bahwa itu tidak membawa sendiri implementasi default.Anda harus selalu mengesampingkan fungsi abstrak.
Jadi:
sumber
Fungsi Abstrak:
Fungsi Virtual:
sumber
Metode abstrak: Ketika suatu kelas berisi metode abstrak, kelas itu harus dinyatakan sebagai abstrak. Metode abstrak tidak memiliki implementasi dan dengan demikian, kelas yang berasal dari kelas abstrak itu, harus menyediakan implementasi untuk metode abstrak ini.
Metode virtual: Suatu kelas dapat memiliki metode virtual. Metode virtual memiliki implementasi. Ketika Anda mewarisi dari kelas yang memiliki metode virtual, Anda bisa mengganti metode virtual dan memberikan logika tambahan, atau mengganti logika dengan implementasi Anda sendiri.
Kapan harus menggunakan apa: Dalam beberapa kasus, Anda tahu bahwa tipe tertentu harus memiliki metode tertentu, tetapi, Anda tidak tahu implementasi apa yang harus dimiliki metode ini.
Dalam kasus seperti itu, Anda bisa membuat antarmuka yang berisi metode dengan tanda tangan ini. Namun, jika Anda memiliki kasus seperti itu, tetapi Anda tahu bahwa implementator dari antarmuka itu juga akan memiliki metode umum lainnya (yang Anda sudah bisa menyediakan implementasinya), Anda dapat membuat kelas abstrak. Kelas abstrak ini kemudian berisi metode abstrak (yang harus diganti), dan metode lain yang berisi logika 'umum'.
Metode virtual harus digunakan jika Anda memiliki kelas yang dapat digunakan secara langsung, tetapi Anda ingin pewaris dapat mengubah perilaku tertentu, meskipun tidak wajib.
sumber
Penjelasan: dengan analogi. semoga akan membantu Anda.
Konteks
Saya bekerja di lantai 21 gedung. Dan saya paranoid tentang api. Sesekali, di suatu tempat di dunia, api membakar alat pencakar langit. Tapi untungnya kami memiliki petunjuk penggunaan di suatu tempat di sini tentang apa yang harus dilakukan jika terjadi kebakaran:
FireEscape ()
Ini pada dasarnya adalah metode virtual yang disebut FireEscape ()
Metode Virtual
Rencana ini cukup bagus untuk 99% keadaan. Ini rencana dasar yang berhasil. Tetapi ada kemungkinan 1% bahwa jalan keluar api terhalang atau rusak sehingga Anda benar-benar kacau dan Anda akan bersulang kecuali Anda melakukan tindakan drastis. Dengan metode virtual, Anda dapat melakukan hal itu: Anda dapat mengganti paket FireEscape () dasar dengan versi paket Anda sendiri:
Dengan kata lain metode virtual menyediakan rencana dasar, yang dapat ditimpa jika Anda perlu . Subclass dapat menggantikan metode virtual kelas induk jika programmer menganggapnya tepat.
Metode abstrak
Tidak semua organisasi dibor dengan baik. Beberapa organisasi tidak melakukan latihan kebakaran. Mereka tidak memiliki kebijakan pelarian secara keseluruhan. Setiap orang adalah untuk dirinya sendiri. Manajemen hanya tertarik pada kebijakan yang ada.
Dengan kata lain, setiap orang dipaksa untuk mengembangkan metode FireEscape () sendiri. Seorang pria akan keluar dari api unggun. Pria lain akan parasut. Seorang pria lain akan menggunakan teknologi propulsi roket untuk terbang jauh dari gedung. Pria lain akan meluncur keluar. Manajemen tidak peduli bagaimana Anda melarikan diri, asalkan Anda memiliki rencana dasar FireEscape () - jika tidak, Anda dijamin OHS akan turun pada organisasi seperti satu ton batu bata. Inilah yang dimaksud dengan metode abstrak.
Apa perbedaan antara keduanya lagi?
Metode abstrak: sub-kelas dipaksa untuk mengimplementasikan metode FireEscape mereka sendiri. Dengan metode virtual, Anda memiliki rencana dasar yang menunggu Anda, tetapi dapat memilih untuk mengimplementasikannya sendiri jika itu tidak cukup baik.
Sekarang itu tidak terlalu sulit bukan?
sumber
Metode abstrak adalah metode yang harus diterapkan untuk membuat kelas yang konkret. Deklarasi berada dalam kelas abstrak (dan setiap kelas dengan metode abstrak harus kelas abstrak) dan harus diimplementasikan dalam kelas konkret.
Metode virtual adalah metode yang dapat ditimpa dalam kelas turunan menggunakan menimpa, menggantikan perilaku dalam superclass. Jika Anda tidak menimpanya, Anda mendapatkan perilaku asli. Jika Anda melakukannya, Anda selalu mendapatkan perilaku baru. Ini menentang bukan metode virtual, yang tidak bisa ditimpa tetapi dapat menyembunyikan metode asli. Ini dilakukan dengan menggunakan
new
pengubah.Lihat contoh berikut:
Ketika saya instantiate
DerivedClass
dan meneleponSayHello
, atauSayGoodbye
, saya mendapatkan "Hai Di sana" dan "Sampai jumpa". Jika saya meneleponHelloGoodbye
, saya mendapatkan "Halo" dan "Sampai jumpa". Ini karenaSayGoodbye
virtual, dan dapat digantikan oleh kelas turunan.SayHello
hanya disembunyikan, jadi ketika saya memanggilnya dari kelas dasar saya, saya mendapatkan metode asli saya.Metode abstrak secara virtual implisit. Mereka mendefinisikan perilaku yang harus ada, lebih seperti antarmuka.
sumber
Metode abstrak selalu virtual. Mereka tidak dapat memiliki implementasi.
Itulah perbedaan utama.
Pada dasarnya, Anda akan menggunakan metode virtual jika Anda memiliki implementasi 'default' dan ingin mengizinkan keturunan mengubah perilakunya.
Dengan metode abstrak, Anda memaksa keturunan untuk menyediakan implementasi.
sumber
Saya membuat ini lebih sederhana dengan membuat beberapa perbaikan pada kelas-kelas berikut (dari jawaban lain):
sumber
Binding adalah proses pemetaan nama ke unit kode.
Ikatan yang terlambat berarti kita menggunakan namanya, tetapi menunda pemetaan. Dengan kata lain, kami membuat / menyebutkan nama terlebih dahulu, dan membiarkan beberapa proses selanjutnya menangani pemetaan kode untuk nama itu.
Sekarang pertimbangkan:
Jadi, jawaban singkatnya adalah:
virtual
adalah instruksi pengikatan terlambat untuk mesin (runtime) sedangkanabstract
instruksi pengikatan terlambat untuk manusia (programmer)Dengan kata lain,
virtual
berarti:“ Runtime yang terhormat , ikat kode yang sesuai dengan nama ini dengan melakukan yang terbaik: mencari ”
Sedangkan
abstract
artinya:“ Pemrogram yang terhormat , tolong ikat kode yang sesuai dengan nama ini dengan melakukan yang terbaik yang Anda lakukan: menciptakan ”
Demi kelengkapan, kelebihan muatan berarti:
" Kompiler yang terhormat , ikat kode yang sesuai dengan nama ini dengan melakukan yang terbaik, penyortiran ".
sumber
Anda pada dasarnya menggunakan metode virtual ketika Anda ingin pewaris untuk memperluas fungsionalitas JIKA mereka mau.
Anda menggunakan metode abstrak saat Anda ingin pewaris mengimplementasikan fungsi (dan dalam hal ini mereka tidak punya pilihan)
sumber
Metode Virtual :
Virtual berarti kita BISA menimpanya.
Fungsi Virtual memiliki implementasi. Ketika kita mewarisi kelas kita dapat mengganti fungsi virtual dan menyediakan logika kita sendiri.
fungsi di kelas anak (yang dapat dikatakan sebagai konsep
Shadowing).
Metode Abstrak
Abstrak berarti kita HARUS menimpanya.
Fungsi abstrak tidak memiliki implementasi dan harus dalam kelas abstrak.
Itu hanya bisa dideklarasikan. Ini memaksa kelas turunan untuk menyediakan implementasi itu.
Anggota abstrak secara virtual implisit. Abstrak dapat disebut sebagai virtual murni di beberapa bahasa.
sumber
Saya telah melihat di beberapa tempat metode abstrak didefinisikan seperti di bawah ini. **
** Saya merasa seperti.
Tidak perlu bahwa metode abstrak harus diimplementasikan dalam kelas anak, jika kelas anak juga abstrak .
1) Metode abstrak tidak bisa menjadi metode pribadi. 2) Metode abstrak tidak dapat diimplementasikan dalam kelas abstrak yang sama.
Saya akan mengatakan .. jika kita menerapkan kelas abstrak, Anda harus mengganti metode abstrak dari kelas abstrak dasar. Karena .. Menerapkan metode abstrak adalah dengan menimpa kata kunci. Mirip dengan metode Virtual.
Metode virtual tidak perlu diimplementasikan di kelas yang diwariskan.
sumber
Sebagian besar contoh di atas menggunakan kode - dan mereka sangat sangat bagus. Saya tidak perlu menambahkan apa yang mereka katakan, tetapi berikut ini adalah penjelasan sederhana yang menggunakan analogi daripada kode / istilah teknis.
Penjelasan Sederhana - Penjelasan menggunakan analogi
Metode Abstrak
Pikirkan George W. Bush. Dia mengatakan kepada tentaranya: "Pergilah berperang di Irak". Dan itu saja. Yang dia telah tentukan adalah bahwa pertempuran harus dilakukan. Dia tidak merinci bagaimana tepatnya hal itu akan terjadi. Tapi maksud saya, Anda tidak bisa keluar begitu saja dan "berkelahi": apa artinya itu sebenarnya? cara saya bertarung dengan B-52 atau derringer saya? Detail spesifik itu diserahkan kepada orang lain. Ini adalah metode abstrak.
Metode Virtual
David Petraeus adalah yang tertinggi di ketentaraan. Dia telah mendefinisikan apa arti pertarungan:
Masalahnya adalah itu adalah metode yang sangat umum. Ini metode yang bagus, tetapi kadang-kadang tidak cukup spesifik. Hal yang baik untuk Petraeus adalah bahwa perintahnya memiliki kelonggaran dan ruang lingkup - ia telah memungkinkan orang lain untuk mengubah definisi "pertarungan", sesuai dengan persyaratan khusus mereka.
Private Job Bloggs membaca pesanan Petraeus dan diberikan izin untuk mengimplementasikan versinya sendiri, sesuai dengan persyaratan khusus:
Nouri al Maliki juga menerima perintah yang sama dari Petraeus. Dia harus bertarung juga. Tapi dia seorang politisi, bukan pria infanteri. Jelas dia tidak bisa berkeliling menembak musuh politiknya di kepala. Karena Petraeus telah memberinya metode virtual, maka Maliki dapat mengimplementasikan versinya sendiri dari metode pertarungan, sesuai dengan keadaan khususnya:
Dengan kata lain, metode virtual memberikan instruksi boilerplate - tetapi ini adalah instruksi umum, yang dapat dibuat lebih spesifik oleh orang-orang di bawah hierarki militer, sesuai dengan keadaan khusus mereka.
Perbedaan keduanya
George Bush tidak membuktikan detail implementasi. Ini harus disediakan oleh orang lain. Ini adalah metode abstrak.
Petraeus di sisi lain memang memberikan detail implementasi tetapi dia telah memberikan izin kepada bawahannya untuk mengesampingkan pesanannya dengan versi mereka sendiri, jika mereka dapat menghasilkan sesuatu yang lebih baik.
berharap itu bisa membantu.
sumber
Fungsi abstrak (metode):
● Metode abstrak adalah metode yang dideklarasikan dengan abstrak kata kunci.
● Tidak memiliki tubuh.
● Ini harus diimplementasikan oleh kelas turunan.
● Jika suatu metode abstrak maka kelas harus abstrak.
fungsi virtual (metode):
● Metode virtual adalah metode yang dideklarasikan dengan kata kunci virtual dan dapat ditimpa oleh metode kelas turunan dengan menggunakan kata kunci override.
● Terserah kelas turunan apakah akan menimpanya atau tidak.
sumber
Jawabannya telah diberikan beberapa kali tetapi pertanyaan tentang kapan harus menggunakan masing-masing adalah keputusan desain-waktu. Saya akan melihatnya sebagai praktik yang baik untuk mencoba menggabungkan definisi metode umum ke dalam antarmuka yang berbeda dan menarik mereka ke dalam kelas pada tingkat abstraksi yang sesuai. Membuang sekumpulan definisi metode abstrak dan virtual ke dalam sebuah kelas menjadikan kelas tidak dapat dibenarkan ketika mungkin yang terbaik adalah mendefinisikan kelas non-abstrak yang mengimplementasikan serangkaian antarmuka ringkas. Seperti biasa, itu tergantung pada apa yang paling sesuai dengan kebutuhan spesifik aplikasi Anda.
sumber
Fungsi abstrak tidak dapat memiliki tubuh dan HARUS ditimpa oleh kelas anak
Fungsi Virtual akan memiliki badan dan mungkin atau mungkin tidak akan ditimpa oleh kelas anak
sumber
Dari tampilan berorientasi objek umum:
Mengenai metode abstrak : Ketika Anda meletakkan metode abstrak di kelas induk sebenarnya Anda katakan kepada kelas anak: Hei perhatikan bahwa Anda memiliki metode tanda tangan seperti ini. Dan jika Anda ingin menggunakannya, Anda harus menerapkannya sendiri!
Mengenai fungsi virtual : Ketika Anda meletakkan metode virtual di kelas induk Anda katakan ke kelas turunan: Hei ada fungsi di sini yang melakukan sesuatu untuk Anda. Jika ini berguna untuk Anda gunakan saja. Jika tidak, timpa ini dan terapkan kode Anda, bahkan Anda dapat menggunakan implementasi saya dalam kode Anda!
ini adalah beberapa filosofi tentang perbedaan antara kedua konsep ini di General OO
sumber
Fungsi abstrak adalah "hanya" tanda tangan, tanpa implementasi. Ini digunakan dalam antarmuka untuk menyatakan bagaimana kelas dapat digunakan. Itu harus diimplementasikan di salah satu kelas turunan.
Fungsi virtual (metode sebenarnya), adalah fungsi yang Anda deklarasikan juga, dan harus diterapkan di salah satu kelas hierarki warisan.
Contoh turunan dari kelas tersebut, mewarisi implementasi juga, kecuali Anda mengimplementasikannya, di kelas hierarki yang lebih rendah.
sumber
Jika suatu kelas berasal dari kelas abstrak ini, maka ia kemudian dipaksa untuk menimpa anggota abstrak tersebut. Ini berbeda dari pengubah virtual, yang menentukan bahwa anggota dapat ditimpa secara opsional.
sumber
Tidak ada yang memanggil kelas virtual di C #.
Untuk fungsi
Anda dapat memutuskan dengan kebutuhan Anda.
sumber
Metode abstrak tidak memiliki implementasi. Ini dideklarasikan di kelas induk. Kelas anak bertanggung jawab untuk mengimplementasikan metode itu.
Metode virtual harus memiliki implementasi di kelas induk dan memfasilitasi kelas anak untuk membuat pilihan apakah akan menggunakan implementasi kelas induk atau untuk memiliki implementasi baru untuk dirinya sendiri untuk metode itu di kelas anak.
sumber
Dari latar belakang C ++, C # virtual berhubungan dengan C ++ virtual, sedangkan metode abstrak C # sesuai dengan C ++ fungsi virtual murni
sumber
Fungsi atau metode abstrak adalah "nama operasi" publik yang diekspos oleh suatu kelas, tujuannya, bersama dengan kelas-kelas abstrak, terutama menyediakan bentuk kendala dalam desain objek terhadap struktur yang harus diimplementasikan oleh objek.
Bahkan kelas-kelas yang mewarisi dari kelas abstraknya harus memberikan implementasi untuk metode ini, umumnya kompiler meningkatkan kesalahan ketika mereka tidak.
Menggunakan kelas dan metode abstrak adalah penting terutama untuk menghindari hal itu dengan berfokus pada detail implementasi ketika merancang kelas, struktur kelas terlalu terkait dengan implementasi, sehingga menciptakan ketergantungan dan penggabungan antara kelas yang berkolaborasi di antara mereka.
Fungsi atau metode virtual hanyalah metode yang memodelkan perilaku publik suatu kelas, tetapi kita dapat membiarkannya memodifikasinya dalam rantai pewarisan, karena kami berpikir bahwa kelas anak mungkin perlu menerapkan beberapa ekstensi spesifik untuk perilaku itu.
Keduanya mewakili bentuk polimorfisme dalam paradigma orientasi objek.
Kita dapat menggunakan metode abstrak dan fungsi virtual bersama untuk mendukung model pewarisan yang baik.
Kami merancang struktur abstrak yang baik dari objek utama dari solusi kami, kemudian membuat implementasi dasar dengan menempatkan mereka yang lebih rentan terhadap spesialisasi lebih lanjut dan kami menjadikannya sebagai virtual, akhirnya kami mengkhususkan implementasi dasar kami, yang akhirnya "menimpa" yang diwarisi virtual.
sumber
Di sini saya menulis beberapa kode contoh berharap ini bisa menjadi contoh yang agak nyata untuk melihat perilaku antarmuka, kelas abstrak dan kelas biasa pada tingkat yang sangat dasar. Anda juga dapat menemukan kode ini di github sebagai proyek jika Anda ingin menggunakannya sebagai demo: https://github.com/usavas/JavaAbstractAndInterfaceDemo
sumber
Untuk pemahaman saya:
Metode Abstrak:
Hanya kelas abstrak yang dapat menampung metode abstrak. Juga kelas turunan perlu mengimplementasikan metode dan tidak ada implementasi yang disediakan di kelas.
Metode Virtual:
Kelas dapat mendeklarasikan ini dan juga menyediakan implementasi yang sama. Juga kelas turunan perlu mengimplementasikan metode untuk menimpanya.
sumber