توی این قسمت هر آنچه از ارث بری رو که بلد بودم، یکجا جمع کردم که درکش راحت تر باشه
توی جلسات قبلی(لینکشون توی پروفایلم هستن) راجع به prototype inheritance صحبت کردیم
و سه تکنیک ساخت برنامه شی گرا با constructor function و ES6 Class و Object.create رو یاد گرفتیم و همشون این اجازه رو به آبجکت میدن که متد ها و پراپرتی هارو توسط prototype رو به ارث ببره
اما چیزی که توی این مقاله میخواییم بگیم، ارث بری بین کلاس هاست نه ارث بری prototype و حواستون باشه این دوتا یعنی ارث بری بین دوتا کلاس و ارث بری prototype رو باهم اشتباه نگیرید.
توی ارث بری کلاس ها، به کلاس والد parent یا class میگن و به کلاس فرزند child یا subclass میگن
اول بریم ارث بری رو توی constructor function بررسی کنیم:
مثال زیر رو دقت کنید، دوتا constructor داریم یکی Person که میشه کلاس والد و یکی Student که میشه کلاس child ما و هرکدوم از این ها هم متد و پراپرتی خودشونو دارن(خط به خط کد زیر رو توضیح خواهم داد فقط زیر چشمی نگاهتون بهش باشه 😏)
توی کلاس Student ما نیاز به firstName و birthday داریم اما اگه بیاییم مثل کلاس والد باز تعریفشون کنیم اصل DRY رو زیر پا میزاریم و کد تکراری میشه پس از متد call برای به ارث بردنشون از کلاس والد استفاده میکنیم
خب تا اینجای کار دوتا کلاس، constructor اشون باهم مچ شدن ولی method هاشون چی ؟ چطوری کلاس فرزند متد های کلاس والد رو به ارث ببره و بتونه بهشون دسترسی داشته باشه ؟
فقط کافیه prototype هاشون رو با خط شماره 17 توی مثال به هم وصل کنیم با این کار کلاس فرزند هر آنچه که کلاس والد داره رو به ارث میبره
حالا یه سوال ممکنه پیش بیاد، چرا از Object.create استفاده کردیم؟ خب میشه توسط خط 19 پروتوتایپ والد رو بریزیم توی فرزند دیگه چکاریه آخه از Object.create استفاده کنیم 🤔
یکم عمیق ترمون نشه😉 ؟؟؟ (دیاگرام زیر رو ببینید) اگه به جای Object.create از خط 19 استفاده کنیم، داریم به جاواسکریپت میگیم که بیا پروتوتایپ والد(Person) رو بزار توی پروتوتایپ فرزند(Student) پس عملا این وسط داریم Student.prototype رو حذف میکنیم و prototype chain (آموزش prototype chain) ما از بین میره،
فقط کافیه یه بار خط 19 رو بزارید توی کد هاتون یه بارم با Object.create امتحان کنید و از mike لاگ بگیرید تا بهتر درکش کنید چه اتفاقی میوفته اگه از خط 19 استفاده کنیم پس کلا فراموشش کن خط 19 رو
خب حالا وقتی یه متد از متد های Person رو روی mike که از Student ساخته شده صدا کنیم، جاواسکریپت چطور این متد رو پیدا میکنه ؟( بازم دیاگرام زیر رو هنگام توضیحات ببینید)
وقتی mike.calcAge() رو صدا میزنیم، جاواسکریپت اول از همه میره _ _ proto_ _ آبجکت mike رو میگرده اگه پیدا کرد که هیچی اگه پیدا نکرد میره سمت پروتوتایپ Student اگه بازم پیدا نکرد میره پروتوتایپه Person رو میگرده و اگرم پیدا نشد هیچی null برمیگرده.
این است قدرت prototype chain 😎
نکته : فقط یه مشکل کوچولویی پیش میاد این وسط اینه که وقتی خط زیر رو لاگ بگیرید
Student.prototype.constructor
میاد constructor عه Person رو نشون میده پس با کد زیر این مشکل رو حل میکنیم
Student.prototype.constructor = Student
حالا دیگه constructor عه Student رو نشون میده
نکته: اگه بخواییم یک متد از Person رو توی کلاس Student به اصطلاح override کنیم یعنی باز نویسیش کنیم باید دقیقا اسم همون متد رو بنویسیم و بعدشم لاجیک مربوطه رو پیاده سازی کنیم و چون فهمیدید javascript چطور یه متد رو پیدا میکنه پس دیگه میبینه خود Student اون متد رو داره پس دیگه سراغ والد نمیره
بریم ارث بری توی ES6 Class رو بررسی کنیم:
همون طور که توی قسمت های قبلی مقاله های شی گرایی گفتم، جاواسکریپت چیزی به اسم class نداره و این class که توی ES6 اضافه شده فقط یه پوسته اس و پس قضیه توسط constructor function ها هندل میشه بنابراین، ارث بری توی ES6 Class دقیقا همین اتفاقات بالا رخ میده فقط از نظر سینتکسی فرق میکنه
مثال زیر رو ببینید و مقایسه اش کنید با ورژن constructor function اش که بالاتر مثالش هست
همه چیز کاملا شفافه فقط چندتا نکته راجع به کد بالا بگم:
توی ES6 Class برای ارث بری بین کلاس والد و فرزند به جای خط زیر از کلمه کلیدی extends استفاده میکنیم
PersonProto.init.call(this, firstName, birthday);
تابع constructor هم که معلومه چیکار میکنه و برای اینکه از مقادیر constructor تابع والد بخواییم استفاده کنیم اومدیم به جای متد call از کلمه کلیدی super استفاده کردیم و کلمه کلیدی Super هم اسمش با خودشه میاد از superclass یعنی کلاس والد مقادیر رو میگیره
و اما آخرین نوع ارث بری هم مربوط میشه Object.create
اگه نمیدونید چیه و چطور کار میکنه این مقاله رو بخون، اگرم میدونی چیه که خب مثال زیر رو ببین تا توضیح بدم ارث بری چطوری داخلش هندل میشه
خب توی خط اول اومدیم یه پروتو برای Person ساختیم به اسم PersonProto و توسط Object.create ازش یک آبجکت ساختیم و ریختیمش توی steven حالا استیون یک شی هست که proto اش، PersonProto هست(تابع init حکم constructor رو بازی میکنه ولی اصلا خاصیت یک constructor رو نداره تو مقاله قبل گفتمش)
حالا میخواییم یه کلاس فرزند داشته باشیم به اسم Student که تمام ویژگی های کلاس والدش یعنی Person رو داشته باشه
خب کاری نداره که توی خط 14 باز از همون پروتوعه Person استفاده کردیم و به همین راحتی کل ویژگی هارو به ارث میبره و خب مثل مثال های قبل توی خط 16 اومدیم init رو override کردیم و توی خط 21 هم کلا یه متد جدید به Student اضاف کردیم
حالا jay توی خط 25 یک شی هست که از proto اش StudentProto هست و به تمام متد های PersonProto دسترسی داره (به خاطر خط 14)
دیاگرام زیر هم به صورت شهودی داره میگه که ارث بری توی Object.create چطور کار میکنه
این شد کل ارث بری توی جاواسکریپت، چیزی نمونده بود که نگم و تا جایی که تونستم چیزایی که یاد گرفتم رو یک جا جمع کردم که مرجع خوبی بشه
امیدوارم بدردت خورده باشه❤️
کانال تلگرامم 👈 LeanByLearn@