Pengenalan
Dalam artikel ini, kami mempertimbangkan pelbagai aspek pengaturcaraan berorientasikan objek dalam ECMAScript (walaupun topik ini telah dibincangkan dalam banyak artikel sebelum ini). Kami akan melihat isu-isu ini lebih daripada perspektif teori. Khususnya, kami akan mempertimbangkan algoritma penciptaan objek, bagaimana objek berkaitan (termasuk hubungan asas - warisan), yang juga boleh digunakan dalam perbincangan (yang saya harap akan menghilangkan beberapa kekaburan konsep sebelumnya tentang OOP dalam JavaScript).
Teks asal bahasa Inggeris:http://dmitrysoshnikov.com/ecmascript/chapter-7-1-oop-general-theory/
Pengenalan, paradigma dan idea
Sebelum menjalankan analisis teknikal OOP dalam ECMAScript, kami perlu menguasai beberapa ciri asas OOP dan menjelaskan konsep utama dalam pengenalan.
ECMAScript menyokong pelbagai kaedah pengaturcaraan termasuk berstruktur, berorientasikan objek, berfungsi, imperatif, dll. Dalam sesetengah kes, ia juga menyokong pengaturcaraan berorientasikan aspek tetapi artikel ini membincangkan pengaturcaraan berorientasikan objek, jadi di sini ialah objek-; pengaturcaraan berorientasikan dalam ECMAScript Definisi:
ECMAScript ialah bahasa pengaturcaraan berorientasikan objek berdasarkan pelaksanaan prototaip.
Terdapat banyak perbezaan antara OOP berasaskan prototaip dan pendekatan berasaskan kelas statik. Mari kita lihat perbezaan mereka secara terperinci.
Berdasarkan atribut kelas dan berdasarkan prototaip
Perhatikan bahawa satu perkara penting telah dinyatakan dalam ayat sebelumnya - sepenuhnya berdasarkan kelas statik. Dengan perkataan "statik" kami memahami objek statik dan kelas statik, ditaip dengan kuat (walaupun tidak diperlukan).
Mengenai situasi ini, banyak dokumen di forum telah menekankan bahawa ini adalah sebab utama mengapa mereka membantah membandingkan "kelas dengan prototaip" dalam JavaScript, walaupun pelaksanaannya berbeza (seperti berdasarkan kelas dinamik) Python dan Ruby) tidak terlalu menentang fokus (beberapa syarat ditulis, walaupun terdapat perbezaan tertentu dalam pemikiran, JavaScript tidak menjadi begitu alternatif), tetapi tumpuan penentangan mereka adalah kelas statik vs. prototaip dinamik ), tepatnya, mekanisme daripada kelas statik (contohnya: C, JAVA) dan subordinatnya serta takrifan kaedah membolehkan kita melihat perbezaan yang tepat antara kelas itu dan pelaksanaan berasaskan prototaip.
Tetapi mari kita senaraikan satu persatu. Mari kita pertimbangkan prinsip umum dan konsep utama paradigma ini.
Berdasarkan kelas statik
Dalam model berasaskan kelas, terdapat konsep kelas dan kejadian. Contoh kelas juga sering dinamakan objek atau kejadian.
Kelas dan Objek
Kelas mewakili abstraksi suatu contoh (iaitu, objek). Ia agak seperti matematik dalam hal ini, tetapi kami memanggilnya jenis atau klasifikasi.
Sebagai contoh (contoh di sini dan di bawah ialah pseudokod):
Warisan berhierarki
Untuk meningkatkan penggunaan semula kod, kelas boleh dilanjutkan dari satu ke satu sama lain, menambah maklumat tambahan. Mekanisme ini dipanggil warisan (hierarki).
Apabila memanggil kaedah pada contoh kelas, anda biasanya akan mencari kaedah dalam kelas asli Jika tidak ditemui, pergi ke kelas induk langsung untuk mencari Jika belum ditemui, pergi ke kelas induk kelas induk untuk mencari (Contohnya, dalam rantaian warisan yang ketat), jika bahagian atas warisan ditemui tetapi belum ditemui, hasilnya ialah: objek tidak mempunyai kelakuan yang serupa dan tiada cara untuk mendapatkan hasilnya.
Konsep utama berdasarkan kelas
Oleh itu, kami mempunyai konsep utama berikut:1. Sebelum mencipta objek, kelas mesti diisytiharkan terlebih dahulu, adalah perlu untuk menentukan kelasnya
2. Oleh itu, objek akan dicipta daripada kelas yang diabstraksikan ke dalam "ikonogram dan persamaan" (struktur dan kelakuan)nya sendiri
3. Kaedah diproses melalui rantaian warisan yang ketat, langsung dan tidak berubah
4. Subkelas mengandungi semua atribut dalam rantaian warisan (walaupun beberapa atribut tidak diperlukan oleh subkelas itu);
5. Buat contoh kelas. Kelas tidak boleh (kerana model statik) mengubah ciri (sifat atau kaedah) contohnya;
6. Kejadian (kerana model statik yang ketat) tidak boleh mempunyai gelagat atau atribut tambahan selain daripada yang diisytiharkan dalam kelas yang sepadan dengan contoh.
Mari lihat cara menggantikan model OOP dalam JavaScript, yang kami cadangkan berdasarkan prototaip OOP.
Konsep asas di sini ialah objek boleh ubah dinamik. Transformasi (transformasi lengkap, termasuk bukan sahaja nilai tetapi juga atribut) berkaitan secara langsung dengan bahasa dinamik. Objek seperti berikut boleh menyimpan semua sifatnya (sifat, kaedah) secara bebas tanpa memerlukan kelas.
Prototaip ialah objek yang digunakan sebagai salinan primitif objek lain, atau jika sesetengah objek tidak mempunyai sifat yang diperlukan sendiri, prototaip boleh digunakan sebagai perwakilan untuk objek ini dan berfungsi sebagai objek tambahan .
Berasaskan perwakilan
Sebarang objek boleh digunakan sebagai objek prototaip untuk objek lain, kerana objek boleh menukar prototaipnya secara dinamik pada masa jalan dengan mudah.
Perhatikan bahawa kami sedang mempertimbangkan gambaran keseluruhan dan bukannya pelaksanaan khusus Apabila kami membincangkan pelaksanaan khusus dalam ECMAScript, kami akan melihat beberapa ciri mereka sendiri.Contoh (pseudokod):
Contoh ini menunjukkan fungsi dan mekanisme penting prototaip sebagai atribut objek tambahan, sama seperti meminta atributnya sendiri Berbanding dengan atributnya sendiri, atribut ini adalah atribut perwakilan. Mekanisme ini dipanggil perwakilan, dan model prototaip berdasarkannya ialah prototaip perwakilan (atau prototaip berasaskan perwakilan). Mekanisme rujukan di sini dipanggil menghantar mesej kepada objek Jika objek tidak mendapat respons, ia akan diwakilkan kepada prototaip untuk mencarinya (memerlukannya untuk cuba membalas mesej tersebut).
Penggunaan semula kod dalam kes ini dipanggil warisan berasaskan perwakilan atau warisan berasaskan prototaip. Memandangkan sebarang objek boleh digunakan sebagai prototaip, ini bermakna prototaip juga boleh mempunyai prototaip sendiri. Prototaip ini dihubungkan bersama untuk membentuk rantai prototaip yang dipanggil. Rantaian juga berhierarki seperti kelas statik, tetapi ia boleh disusun semula dengan mudah untuk menukar hierarki dan struktur.
Jika objek dan rantai prototaipnya tidak dapat bertindak balas kepada penghantaran mesej, objek boleh mengaktifkan isyarat sistem yang sepadan, mungkin dikendalikan oleh perwakilan lain pada rantai prototaip.
Isyarat sistem ini tersedia dalam banyak pelaksanaan, termasuk sistem berdasarkan kelas dinamik kurungan: #doesNotUnderstand dalam Smalltalk, method_missing dalam Ruby, __call dalam PHP dan __noSuchMethod__ pelaksanaan dalam ECMAScript, dsb.
Contoh (pelaksanaan ECMAScript SpiderMonkey):
Dalam erti kata lain, jika pelaksanaan berdasarkan kelas statik tidak dapat bertindak balas kepada mesej, kesimpulannya ialah objek semasa tidak mempunyai ciri yang diperlukan, tetapi jika anda cuba mendapatkannya daripada rantai prototaip, anda mungkin masih dapatkan hasilnya , atau objek mempunyai ciri ini selepas beberapa siri perubahan.
Mengenai ECMAScript, pelaksanaan khusus ialah: menggunakan prototaip berasaskan perwakilan. Walau bagaimanapun, seperti yang akan kita lihat dari spesifikasi dan pelaksanaan, mereka juga mempunyai ciri-ciri mereka sendiri.
Model Gabungan
Sejujurnya, adalah perlu untuk mengatakan sesuatu tentang situasi lain (sebaik sahaja ia tidak digunakan dalam ECMASCript): keadaan apabila prototaip menggantikan objek asli daripada objek lain. Penggunaan semula kod dalam kes ini ialah salinan sebenar (klon) objek semasa fasa penciptaan objek dan bukannya perwakilan. Prototaip jenis ini dipanggil prototaip concatenative. Menyalin semua sifat prototaip objek boleh mengubah sepenuhnya sifat dan kaedahnya, dan prototaip juga boleh mengubah dirinya sendiri (dalam model berasaskan perwakilan, perubahan ini tidak akan mengubah kelakuan objek sedia ada, tetapi mengubah sifat prototaipnya) . Kelebihan kaedah ini ialah ia dapat mengurangkan masa penjadualan dan delegasi, tetapi kelemahannya ialah penggunaan memori adalah tinggi.
Jenis Itik
Memulangkan objek yang menukar jenis lemah secara dinamik Berbanding dengan model berdasarkan kelas statik, menguji sama ada ia boleh melakukan perkara ini tiada kaitan dengan jenis (kelas) objek, tetapi sama ada ia boleh bertindak balas kepada mesej (yang. ialah, selepas menyemak sama ada Keupayaan untuk melakukannya adalah satu kemestian).
Contohnya:
Inilah yang dipanggil jenis Dok. Iaitu, objek boleh dikenal pasti dengan ciri-ciri mereka sendiri apabila menyemak, bukannya kedudukan objek dalam hierarki atau kepunyaan mereka kepada mana-mana jenis tertentu.
Konsep utama berdasarkan prototaip
Mari kita lihat ciri utama pendekatan ini:
1. Konsep asas ialah objek
2. Objek benar-benar dinamik dan berubah-ubah (secara teorinya ia boleh ditukar dari satu jenis ke jenis yang lain)
3. Objek tidak mempunyai kelas ketat yang menerangkan struktur dan tingkah lakunya sendiri. Objek tidak memerlukan kelas
4. Objek tidak mempunyai kelas tetapi boleh mempunyai prototaip Jika mereka tidak dapat membalas mesej, mereka boleh diwakilkan kepada prototaip
5. Prototaip objek boleh ditukar pada bila-bila masa semasa runtime;
6. Dalam model berasaskan perwakilan, mengubah ciri prototaip akan menjejaskan semua objek yang berkaitan dengan prototaip;
7. Dalam model prototaip gabungan, prototaip ialah salinan asal yang diklon daripada objek lain, dan seterusnya menjadi salinan asal yang bebas sepenuhnya Perubahan ciri prototaip tidak akan menjejaskan objek yang diklon daripadanya
8. Jika mesej tidak dapat dibalas, pemanggilnya boleh mengambil langkah tambahan (cth., menukar penjadualan)
9. Kegagalan objek tidak boleh ditentukan oleh tahap mereka dan kelas mana mereka tergolong, tetapi oleh ciri semasa
Walau bagaimanapun, terdapat model lain yang juga harus kita pertimbangkan.
Berdasarkan kelas dinamik
Kami percaya bahawa perbezaan "prototaip kelas VS" yang ditunjukkan dalam contoh di atas tidak begitu penting dalam model ini berdasarkan kelas dinamik, (terutamanya jika rantaian prototaip tidak boleh diubah, untuk perbezaan yang lebih tepat, ia masih perlu pertimbangkan kelas statik). Sebagai contoh, ia juga boleh menggunakan Python atau Ruby (atau bahasa lain yang serupa). Bahasa-bahasa ini semuanya menggunakan paradigma berasaskan kelas dinamik. Walau bagaimanapun, dalam beberapa aspek kita boleh melihat beberapa fungsi dilaksanakan berdasarkan prototaip.
Dalam contoh berikut, kita dapat melihat bahawa hanya berdasarkan delegasi, kita boleh membesarkan kelas (prototaip), dengan itu mempengaruhi semua objek yang berkaitan dengan kelas ini Kita juga boleh menukar objek ini secara dinamik pada masa runtime objek untuk perwakilan) dan sebagainya.
Pelaksanaan dalam Ruby adalah serupa: kelas dinamik sepenuhnya juga digunakan (dengan cara dalam versi Python semasa, berbeza dengan Ruby dan ECMAScript, pembesaran kelas (prototaip) tidak berfungsi), kita boleh menukar objek sepenuhnya (atau kelas) ciri (menambah kaedah/sifat pada kelas, dan perubahan ini akan menjejaskan objek sedia ada), namun, ia tidak boleh menukar kelas objek secara dinamik.
Walau bagaimanapun, artikel ini tidak khusus mengenai Python dan Ruby, jadi kami tidak akan bercakap lebih lanjut dan mari terus membincangkan ECMAScript itu sendiri.
Tetapi sebelum itu, kita perlu melihat sekali lagi tentang "gula sintaksis" yang terdapat dalam beberapa OOP, kerana banyak artikel terdahulu tentang JavaScript sering merangkumi isu ini.
Satu-satunya ayat yang salah untuk diperhatikan dalam bahagian ini ialah: "JavaScript bukan kelas, ia mempunyai prototaip, yang boleh menggantikan kelas." Adalah penting untuk mengetahui bahawa tidak semua pelaksanaan berasaskan kelas adalah sama sekali berbeza Walaupun kita mungkin mengatakan "JavaScript adalah berbeza", ia juga perlu mempertimbangkan bahawa (sebagai tambahan kepada konsep "kelas") terdapat ciri lain yang berkaitan. .
Ciri lain pelbagai pelaksanaan OOP
Dalam bahagian ini kami memperkenalkan secara ringkas ciri dan kaedah penggunaan semula kod lain dalam pelbagai pelaksanaan OOP, termasuk pelaksanaan OOP dalam ECMAScript. Sebabnya ialah terdapat beberapa sekatan pemikiran lazim pada pelaksanaan OOP dalam JavaScript Satu-satunya keperluan utama ialah ia harus dibuktikan secara teknikal dan ideologi. Ia tidak boleh dikatakan bahawa kami tidak menemui fungsi gula sintaksis dalam pelaksanaan OOP lain, dan kami dengan tergesa-gesa menganggap bahawa JavaScript bukan bahasa OOP tulen Ini adalah salah.
Polimorfik
Objek mempunyai beberapa makna polimorfisme dalam ECMAScript.
Sebagai contoh, fungsi boleh digunakan pada objek yang berbeza, sama seperti sifat objek asli (kerana nilai ditentukan apabila memasuki konteks pelaksanaan):
Apa yang dipanggil polimorfisme parameter apabila mentakrifkan fungsi adalah setara dengan semua jenis data, kecuali ia menerima parameter polimorfik (seperti kaedah pengisihan .sort tatasusunan dan parameternya - fungsi pengisihan polimorfik). Dengan cara ini, contoh di atas juga boleh dianggap sejenis polimorfisme parametrik.
Kaedah dalam prototaip boleh ditakrifkan sebagai kosong dan semua objek yang dicipta harus mentakrifkan semula (melaksanakan) kaedah ini (iaitu "satu antara muka (tandatangan), berbilang pelaksanaan").
Polymorphism berkaitan dengan jenis Itik yang kami nyatakan di atas: iaitu jenis dan kedudukan objek dalam hierarki tidak begitu penting, tetapi jika ia mempunyai semua ciri yang diperlukan, ia boleh diterima dengan mudah (iaitu antara muka biasa adalah penting , pelaksanaan boleh menjadi pelbagai).
Ekapsulasi
Selalunya terdapat salah tanggapan tentang pengkapsulan. Dalam bahagian ini kita membincangkan beberapa gula sintaksis dalam pelaksanaan OOP - juga dikenali sebagai pengubah: Dalam kes ini, kita akan membincangkan beberapa kemudahan "gula" dalam pelaksanaan OOP - pengubah yang terkenal: peribadi, dilindungi dan awam ( Atau dikenali sebagai akses objek tahap atau pengubah suai akses).
Di sini saya ingin mengingatkan anda tentang tujuan utama enkapsulasi: enkapsulasi ialah penambahan abstrak, bukan "penggodam berniat jahat" tersembunyi yang menulis sesuatu terus ke dalam kelas anda.
Ini adalah kesilapan besar: gunakan sorok demi menyembunyikan.
Tahap akses (peribadi, dilindungi dan awam) telah dilaksanakan dalam banyak program berorientasikan objek untuk memudahkan pengaturcaraan (gula sintaks yang sangat mudah), menerangkan dan membina sistem dengan lebih abstrak.
Ini boleh dilihat dalam beberapa pelaksanaan (seperti Python dan Ruby yang telah disebutkan). Di satu pihak (dalam Python), atribut __private_protected ini (dinamakan melalui konvensyen garis bawah) tidak boleh diakses dari luar. Python, sebaliknya, boleh diakses dari luar dengan peraturan khas (_ClassName__field_name).
Dalam Ruby: Di satu pihak, ia mempunyai keupayaan untuk menentukan ciri peribadi dan dilindungi Sebaliknya, terdapat juga kaedah khas (seperti instance_variable_get, instance_variable_set, send, dll.) untuk mendapatkan data terkapsul.
Sebab utamanya ialah pengaturcara sendiri ingin mendapatkan data yang dikapsulkan (perhatikan bahawa saya secara khusus tidak menggunakan data "tersembunyi"). Jika data ini berubah secara tidak betul dalam beberapa cara atau mempunyai sebarang ralat, tanggungjawab penuh terletak pada pengaturcara, tetapi bukan hanya "ralat menaip" atau "hanya menukar beberapa medan". Tetapi jika ini berlaku dengan kerap, ia adalah tabiat dan gaya pengaturcaraan yang sangat buruk, kerana ia biasanya bernilai menggunakan API awam untuk "bercakap" dengan objek.
Untuk mengulangi, tujuan asas enkapsulasi adalah untuk mengabstrak pengguna data tambahan, bukan untuk menghalang penggodam daripada menyembunyikan data. Lebih serius, enkapsulasi tidak menggunakan persendirian untuk mengubah suai data untuk mencapai keselamatan perisian.
Mengenkapsulkan objek tambahan (sebahagian) Kami menggunakan kos minimum, penyetempatan dan perubahan ramalan untuk memberikan kebolehlaksanaan untuk perubahan tingkah laku dalam antara muka awam.
Selain itu, tujuan penting kaedah penetap adalah untuk mengabstraksi pengiraan kompleks. Sebagai contoh, penetap element.innerHTML - pernyataan abstrak - "HTML di dalam elemen ini sekarang ialah kandungan berikut", dan fungsi penetap dalam sifat innerHTML akan menjadi sukar untuk dikira dan diperiksa. Dalam kes ini, masalah kebanyakannya melibatkan abstraksi, tetapi enkapsulasi juga berlaku.
Konsep enkapsulasi bukan sahaja berkaitan dengan OOP. Sebagai contoh, ia boleh menjadi fungsi mudah yang hanya merangkum pelbagai pengiraan, menjadikannya abstrak (tidak perlu untuk pengguna mengetahui, sebagai contoh, bagaimana fungsi Math.round(...) dilaksanakan, pengguna hanya memanggil ia). Ia adalah sejenis enkapsulasi. Perhatikan bahawa saya tidak mengatakan ia adalah "peribadi, dilindungi dan awam".
Versi semasa spesifikasi ECMAScript tidak mentakrifkan pengubah suai peribadi, dilindungi dan awam.
Walau bagaimanapun, dalam amalan adalah mungkin untuk melihat sesuatu yang dinamakan "Mock JS Encapsulation". Secara amnya konteks ini bertujuan untuk digunakan (sebagai peraturan, pembina itu sendiri). Malangnya, "mimikri" ini sering dilaksanakan dan pengaturcara boleh menghasilkan tetapan entiti pseudo-benar-benar bukan abstrak "kaedah getter/setter" (saya ulangi, ia adalah salah):
Jadi, semua orang faham bahawa untuk setiap objek yang dicipta, kaedah getA/setA juga dicipta, yang juga merupakan sebab peningkatan dalam ingatan (berbanding dengan definisi prototaip). Walaupun, secara teori objek boleh dioptimumkan dalam kes pertama.
Selain itu, beberapa artikel JavaScript sering menyebut konsep "kaedah peribadi".
Walau bagaimanapun, dalam beberapa kes ia boleh dibuat dalam pembina, kerana JS ialah bahasa ideologi - objek boleh berubah sepenuhnya dan mempunyai ciri unik (di bawah keadaan tertentu dalam pembina, sesetengah objek boleh mendapatkan kaedah tambahan manakala yang lain tidak ).
Selain itu, dalam JavaScript, jika enkapsulasi masih disalahtafsirkan sebagai pemahaman yang menghalang penggodam berniat jahat daripada menulis nilai tertentu secara automatik dan bukannya menggunakan kaedah penetap, maka apa yang dipanggil "tersembunyi" dan " "peribadi" sebenarnya tidak terlalu "tersembunyi", sesetengah pelaksanaan boleh mendapatkan nilai pada rantai skop yang berkaitan (dan sepadan dengan semua objek pembolehubah) dengan memanggil konteks ke fungsi eval (boleh diuji pada SpiderMonkey1.7).
Sebagai alternatif, pelaksanaan membenarkan akses terus kepada objek aktif (seperti Rhino), dan nilai pembolehubah dalaman boleh diubah dengan mengakses sifat objek yang sepadan:
var _myPrivateData = 'testString';
Ia sering digunakan untuk menyertakan konteks pelaksanaan dalam kurungan, tetapi untuk data tambahan sebenar, ia tidak berkaitan secara langsung dengan objek, tetapi hanya mudah untuk mengabstrakkan daripada API luaran:
Warisan berbilang
Pewarisan berbilang ialah gula sintaksis yang sangat mudah untuk meningkatkan penggunaan semula kod (jika kita boleh mewarisi satu kelas pada satu masa, mengapa kita tidak boleh mewarisi 10 pada satu masa?). Walau bagaimanapun, disebabkan oleh beberapa kekurangan warisan berbilang, ia tidak menjadi popular dalam pelaksanaan.
ECMAScript tidak menyokong berbilang warisan (iaitu hanya satu objek boleh digunakan sebagai prototaip langsung), walaupun bahasa pengaturcaraan nenek moyangnya mempunyai keupayaan sedemikian. Tetapi dalam beberapa pelaksanaan (seperti SpiderMonkey) menggunakan __noSuchMethod__ boleh digunakan untuk mengurus penjadualan dan perwakilan dan bukannya rantai prototaip.
Bancuhan
Mixin ialah cara yang mudah untuk menggunakan semula kod. Mixin telah dicadangkan sebagai alternatif kepada pelbagai warisan. Setiap elemen individu ini boleh dicampur dengan mana-mana objek untuk melanjutkan fungsinya (jadi objek juga boleh dicampur dengan berbilang Mixin). Spesifikasi ECMA-262-3 tidak mentakrifkan konsep "Mixins", tetapi mengikut takrifan Mixins dan ECMAScript mempunyai objek boleh ubah secara dinamik, tiada halangan untuk hanya memanjangkan ciri menggunakan Mixins.
Contoh biasa:
Sila ambil perhatian bahawa saya menggunakan takrifan ini ("mixin", "mix") dalam tanda petikan yang disebut dalam ECMA-262-3 Tiada konsep sedemikian dalam spesifikasi, dan ia bukan campuran tetapi biasa digunakan untuk memanjangkan objek dengan ciri-ciri baharu. (Konsep mixin dalam Ruby ditakrifkan secara rasmi. Mixins mencipta rujukan kepada modul yang mengandungi dan bukannya menyalin semua sifat modul ke modul lain - sebenarnya: mencipta objek tambahan (prototaip) untuk perwakilan. ).
Sifat
Sifat adalah serupa dalam konsep kepada campuran, tetapi ia mempunyai banyak fungsi (mengikut definisi, kerana campuran boleh digunakan, ia tidak boleh mengandungi keadaan, kerana ia boleh menyebabkan konflik penamaan). Menurut ECMAScript, Traits dan mixin mengikut prinsip yang sama, jadi spesifikasi tidak mentakrifkan konsep "Traits".
Antara Muka
Antara muka yang dilaksanakan dalam beberapa OOP adalah serupa dengan campuran dan sifat. Walau bagaimanapun, berbeza dengan campuran dan sifat, antara muka memaksa kelas pelaksana untuk melaksanakan gelagat tandatangan kaedah mereka.
Antara muka boleh dianggap sepenuhnya sebagai kelas abstrak. Walau bagaimanapun, berbanding dengan kelas abstrak (kaedah dalam kelas abstrak hanya boleh melaksanakan sebahagian daripada kaedah, dan bahagian lain masih ditakrifkan sebagai tandatangan), warisan hanya boleh mewarisi kelas asas tunggal, tetapi boleh mewarisi berbilang antara muka. antara muka (pelbagai Campuran) boleh dilihat sebagai alternatif kepada pewarisan berbilang.
Piawaian ECMA-262-3 tidak mentakrifkan konsep "antara muka" mahupun konsep "kelas abstrak". Walau bagaimanapun, sebagai tiruan, adalah mungkin untuk melaksanakan objek dengan kaedah "kosong" (atau pengecualian yang dilemparkan dalam kaedah kosong untuk memberitahu pembangun bahawa kaedah ini perlu dilaksanakan).
Kombinasi objek
Komposisi objek juga merupakan salah satu teknologi penggunaan semula kod dinamik. Komposisi objek berbeza daripada warisan yang sangat fleksibel kerana ia melaksanakan perwakilan yang boleh berubah secara dinamik. Dan ini juga berdasarkan asas prototaip yang ditugaskan. Selain prototaip boleh ubah secara dinamik, objek boleh mengagregat objek untuk perwakilan (mencipta gabungan sebagai hasil - pengagregatan) dan seterusnya menghantar mesej kepada objek yang mewakilkan kepada perwakilan. Ini boleh dilakukan dengan lebih daripada dua perwakilan, kerana sifat dinamiknya bermakna ia boleh berubah semasa masa jalan.
Contoh __noSuchMethod__ yang telah disebutkan melakukan ini, tetapi mari kita tunjukkan juga cara menggunakan perwakilan secara eksplisit:
Contohnya:
Hubungan objek ini dipanggil "mempunyai-a", dan penyepaduan ialah hubungan "adalah-a".
Disebabkan kekurangan komposisi eksplisit (fleksibiliti berbanding warisan), menambah kod perantaraan juga tidak mengapa.
Ciri AOP
Sebagai fungsi berorientasikan aspek, anda boleh menggunakan penghias fungsi. Spesifikasi ECMA-262-3 tidak mentakrifkan dengan jelas konsep "penghias fungsi" (berbanding dengan Python, di mana istilah ini ditakrifkan secara rasmi). Walau bagaimanapun, fungsi dengan parameter berfungsi boleh dihiasi dan diaktifkan dalam aspek tertentu (dengan menggunakan apa yang dipanggil cadangan):
Contoh penghias paling mudah:
Kesimpulan
Dalam artikel ini, kami telah menjelaskan pengenalan OOP (saya harap maklumat ini berguna kepada anda), dan dalam bab seterusnya kami akan meneruskan pelaksanaan ECMAScript untuk pengaturcaraan berorientasikan objek.