Klass merosi
Klass merosi (inheritance) โ bir klassning imkoniyatlarini boshqa klass asosida kengaytirish usuli. Bu bizga mavjud funksionallikni takrorlamasdan qayta ishlatish imkonini beradi.
"extends" kalit so'zi
Aytaylik, Animal (hayvon) klassimiz bor:
Endi Rabbit (quyon) klassini yaratmoqchimiz. Quyon ham hayvon bo'lgani uchun, u Animal imkoniyatlarini meros olishi va o'ziga xos metodlar qo'shishi kerak. Buning uchun extends ishlatamiz:
Rabbit obyekti ham o'zining hide() metodiga, ham Animaldan meros olingan run() metodiga kirish huquqiga ega.
extends Rabbit.prototype.[[Prototype]]ni Animal.prototypega bog'laydi. Shu sababli Rabbitda metod topilmasa, JavaScript uni Animal.prototypedan qidiradi โ bu prototip zanjiri orqali ishlaydi.extendsdan keyin ifoda ham yozilishi mumkin. Masalan, klass generatsiya qiluvchi funksiya chaqiruvi:
function f(phrase) {
return class {
sayHi() { return phrase; }
};
}
class User extends f("Salom") {}
console.log(new User().sayHi()); // Salom
Metodni qayta aniqlash (override)
Endi keling, oldinga borib, metodni qayta aniqlaymiz (override qilamiz). Standart holatda Rabbitda aniqlanmagan barcha metodlar Animaldan "o'z holicha" olinadi. Ammo agar biz Rabbitda o'z stop()imizni yozsak, u ishlatiladi:
super orqali ota metodni chaqirish
Ko'pincha biz ota metodni butunlay almashtirmoqchi emasmiz โ uni asos qilib, ustiga qo'shimcha qilmoqchimiz. Buning uchun super.method(...) orqali ota klassdagi metodni chaqiramiz:
Bu yerda Rabbitning stop() metodi o'zining zanjiridagi super.stop()ni chaqiradi โ ya'ni Animal.prototype.stopni.
supersi yo'q. Agar strelka funksiya ichida superga murojaat qilsangiz, u tashqi metoddan olinadi. Bu ko'pincha foydali xususiyat, chunki strelka funksiyada super "yo'qolib" qolmaydi.Konstruktorni qayta aniqlash
Konstruktor bilan biroz murakkabroq. Hozirgacha Rabbitning o'z constructori yo'q edi. Spetsifikatsiyaga ko'ra, agar meros olgan klassda constructor bo'lmasa, quyidagi "bo'sh" konstruktor avtomatik yaratiladi:
class Rabbit extends Animal {
// meros olgan klass uchun avtomatik generatsiya qilinadi
constructor(...args) {
super(...args);
}
}
Ko'rib turganingizdek, u shunchaki ota constructorini chaqiradi va unga barcha argumentlarni uzatadi. Endi Rabbitga o'z konstruktorimizni qo'shsak, unda albatta super(...)ni chaqirishimiz kerak:
Nima uchun super() shart?
Meros olgan klass konstruktorlari maxsus ichki [[ConstructorKind]]: "derived" belgisiga ega. Bu farq juda muhim:
- Oddiy klassda
newpaytida bo'shthisobyekti darhol yaratiladi; - Meros olgan klass konstruktori esa bu ishni o'zi bajarmaydi โ u buni ota konstruktordan kutadi. Shuning uchun
thisni ishlatishdan oldinsuper()ni chaqirish shart.
super()ni chaqirmasangiz yoki thisga undan oldin murojaat qilsangiz, xatolik chiqadi: "Must call super constructor before accessing 'this'".Xulosa
class Child extends ParentโChildniParentdan meros oldiradi;super.method()โ ota klass metodini chaqiradi;super(...)โ ota konstruktorini chaqiradi (faqat meros olgan konstruktor ichida);- Meros olgan konstruktorda
thisni ishlatishdan oldinsuper()chaqirilishi shart; - Metodni qayta yozib (override),
superorqali eskisini ham ishlatish mumkin.