Selama ulasan kode hari ini, seorang rekan saya mengatakan sesuatu yang menarik:
prototype
hanya berguna ketika Anda membutuhkan warisan - dan kapan warisan merupakan ide bagus ?
Saya memikirkan hal ini dan saya menyadari bahwa saya biasanya menggunakan warisan untuk menyiasati kode yang awalnya dirancang dengan buruk. Gaya OO modern lebih suka komposisi daripada warisan, tetapi saya tidak tahu bahasa apa pun yang telah membawa ini ke hati dan benar-benar menegakkannya .
Apakah ada bahasa pemrograman tujuan umum dengan kelas, objek, metode, antarmuka, dan sebagainya, yang melarang pewarisan berbasis kelas? (Jika ide seperti itu tidak masuk akal, mengapa tidak?)
object-oriented
programming-languages
inheritance
Benjamin Hodgson
sumber
sumber
prototype
juga berguna ketika Anda memiliki metode dan properti publik yang harus dibagi di antara instance. Ini juga berguna karena memungkinkan Anda untuk benar menggunakaninstanceof
operator dalam JavaScript:if (foo instanceof Foo) { ...
.implements
kata kunci dan antarmuka (sebagai lawan dari warisan negara dan perilaku yang diperkenalkan dengan penggunaanextends
kata kunci pada kelas yang berisi implementasi apa pun).new
,this
danprototype
terlalu banyak ladang ranjau untuk penggunaan umum IMO.Jawaban:
Mengesampingkan pertanyaan tentang definisi pemrograman berorientasi objek pertanyaan menjadi salah satu "apakah ada bahasa yang hanya menggunakan komposisi dan tidak memiliki alat untuk pewarisan?"
Jawabannya cukup sederhana "ya". Pada akhirnya, tidak ada cara untuk melakukan warisan seperti yang dipikirkan orang secara klasik. Satu dapat tertanam objek di objek lain dan memperluas objek itu. Dari Object Desoriented Language ( github mirror ):
Anda memiliki struct orang yang memiliki Nama yang merupakan String. Ini memiliki fungsi publik yang disebut Intro yang mengembalikan nama. Struct Wanita juga memiliki fungsi untuk Intro yang mengakses strut yang tertanam di dalamnya. Dan dengan demikian seseorang dapat memenuhi niat pewarisan dengan menggunakan komposisi saja.
Lebih lanjut tentang ini dapat dilihat di GoLang Tutorials: Inheritance dan subclassing di Go - atau yang hampir mirip .
Jadi ya, adalah mungkin untuk memiliki bahasa OO tanpa warisan, dan memang ada.
Dalam go go ini dikenal sebagai embedding dan memberi struktur penutup kemampuan untuk mengakses bidang dan fungsi yang tertanam seolah-olah memilikinya juga - tetapi ini bukan subkelas. Filosofi desain dapat ditemukan di Go FAQ: Mengapa tidak ada pewarisan tipe?
sumber
typedef
danstruct
dalam C ...Ini sangat mirip dengan deskripsi VBA - Visual Basic for Applications, tertanam di Microsoft Office dan host berkemampuan VBA lainnya (mis. AutoCAD, Sage 300 ERP, dll.), Atau bahkan VB6. "A" dari "Basic" adalah singkatan dari "All-purpose", jadi ada bagian "general-purpose".
VB6 / VBA memiliki kelas (dan karenanya objek), metode, dan antarmuka - Anda dapat mendefinisikan
ISomething
antarmuka dalam modul kelas seperti ini:Dan kemudian memiliki kelas lain yang melakukan ini:
Kelas semacam itu, yang tidak memperlihatkan anggota publik, hanya dapat diakses melalui
ISomething
antarmuka - dan mungkin ada puluhan implementasi yang berbeda diISomething
luar sana, sehingga kode OOP VBA sangat mampu melakukan polimorfisme, dan sangat legal untuk kelas tertentu untuk mengimplementasikan beberapa antarmuka juga.VB6 / VBA tidak memungkinkan pewarisan kelas , jadi Anda tidak bisa mewarisi implementasi dari tipe lain, hanya antarmuka-nya. Sekarang, apakah ini kecelakaan, cacat desain, jenius, atau kekeliruan besar terbuka untuk diperdebatkan; tidak jelas apakah VB6 / VBA membawa ini ke hati , tetapi yang paling pasti menegakkannya .
Jika Go tidak melakukan warisan kelas dan tetap merupakan bahasa OOP , maka saya tidak mengerti mengapa VB6 / VBA tidak dapat dianggap sebagai bahasa OOP juga.
</PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>
sumber
Anda dapat membuat kompilator menegakkan pewarisan selektif melalui penggunaan teknik privat / terproteksi, dan melalui modern "PImpl", atau "Implementasi Privat".
Banyak API mengekspos hanya komponen-komponen yang Anda inginkan agar diwarisi oleh pengguna, dan menyembunyikan yang lainnya di kelas implementasi yang terpisah. Jadi, Anda bisa menulis kelas yang antarmuka publiknya, pada kenyataannya, tidak dapat diraih, hanya dapat digunakan melalui komposisi objek, dan kompiler-diberlakukan. Ini sering merupakan praktik yang baik, ketika menggunakan kompiler untuk menegakkan maksud dari perangkat lunak.
Pencarian cepat untuk fungsi anggota pribadi di javascript menunjukkan ada prinsip yang serupa, meskipun siapa pun dapat melihat kode Anda jika mereka dapat menggunakannya: http://www.crockford.com/javascript/private.html
sumber