Class — extends va super
Muammodan boshlaylik
Foydalanuvchi classi bor:
class Foydalanuvchi {
constructor(ism, email) {
this.ism = ism;
this.email = email;
}
info() {
console.log(`${this.ism} — ${this.email}`);
}
}
Endi Admin kerak. Adminda ham ism, email bor — plus qo'shimcha huquqlar va bloklash metodi. Ikkita variant:
1-variant — hamma narsani qaytadan yozish:
class Admin {
constructor(ism, email, huquqlar) {
this.ism = ism; // ← takror
this.email = email; // ← takror
this.huquqlar = huquqlar;
}
info() { ... } // ← takror
bloklash() { ... }
}
2-variant — Foydalanuvchi dan meros olish:
class Admin extends Foydalanuvchi {
constructor(ism, email, huquqlar) {
super(ism, email); // ← Foydalanuvchi konstruktorini chaqirdi
this.huquqlar = huquqlar; // ← faqat qo'shimcha narsa
}
bloklash(foydalanuvchi) {
console.log(`${foydalanuvchi.ism} bloklandi`);
}
}
Takrorlanish yo'q. Bu — meros (inheritance).
extends — meros olish
extends — bir class boshqa classdan barcha xususiyat va metodlarni meros oladi.
Hayotiy o'xshatma
Xodimlar ierarxiyasi. Barcha xodimlar: ism, lavozim, maosh oladi. Menejer — xodim, lekin qo'shimcha: jamoa boshqaradi, hisobot tuzadi. Direktor — menejer, lekin qo'shimcha: strategiya belgilaydi, byudjet tasdiqlaydi.
Har bir daraja oldingisini takrorlamaydi — meros oladi, faqat qo'shimchasini yozadi.
class Xodim {
constructor(ism, maosh) {
this.ism = ism;
this.maosh = maosh;
}
info() {
console.log(`${this.ism}, maosh: ${this.maosh}`);
}
ishlash() {
console.log(`${this.ism} ishlayapti`);
}
}
class Menejer extends Xodim {
constructor(ism, maosh, jamoa) {
super(ism, maosh); // ← Xodim konstruktorini chaqirish shart
this.jamoa = jamoa;
}
yigilishtutish() {
console.log(`${this.ism} yig'ilish o'tkazdi (${this.jamoa} kishi)`);
}
}
const ali = new Xodim("Ali", 5_000_000);
const vali = new Menejer("Vali", 10_000_000, 8);
ali.info(); // "Ali, maosh: 5000000"
vali.info(); // "Vali, maosh: 10000000" ← Xodim dan meros
vali.ishlayapti(); // ← Xodim dan meros
vali.yigilishtutish(); // ← Menejer ning o'zi
super — ota classga murojaat
super — ota classni chaqirish uchun. Ikki shaklda ishlatiladi:
1. Konstruktorda — ota konstruktorini chaqirish:
class Hayvon {
constructor(ism, tur) {
this.ism = ism;
this.tur = tur;
}
}
class It extends Hayvon {
constructor(ism, zot) {
super(ism, "Hayvon"); // ← Hayvon(ism, "Hayvon") ni chaqirdi
this.zot = zot;
}
}
const rex = new It("Rex", "Alabay");
console.log(rex.ism); // "Rex" ← super orqali o'rnatildi
console.log(rex.tur); // "Hayvon"
console.log(rex.zot); // "Alabay"
extends ishlatilgan har bir constructorda super() birinchi qatorda bo'lishi shart. Aks holda — xato.
2. Metodda — ota metodini chaqirish:
class Hayvon {
ovoz() {
console.log("...");
}
}
class It extends Hayvon {
ovoz() {
super.ovoz(); // ← Hayvon.ovoz() ni chaqirdi
console.log("Hav hav!"); // ← qo'shimcha
}
}
class ShovqinliIt extends It {
ovoz() {
super.ovoz(); // ← It.ovoz() ni chaqirdi (u o'z ichida Hayvon.ovoz() ham)
console.log("HAV HAV HAV!!!"); // ← qo'shimcha
}
}
const it = new ShovqinliIt();
it.ovoz();
// "..."
// "Hav hav!"
// "HAV HAV HAV!!!"
Metodni qayta yozish (override)
Bola class ota classning metodini qayta yozishi mumkin:
class Shakllar {
yuzasi() {
return 0;
}
tavsif() {
console.log(`Yuzasi: ${this.yuzasi()}`); // ← polimorfizm: qaysi yuzasi() chaqiriladi?
}
}
class Kvadrat extends Shakllar {
constructor(tomon) {
super();
this.tomon = tomon;
}
yuzasi() { // ← qayta yozildi (override)
return this.tomon ** 2;
}
}
class Doira extends Shakllar {
constructor(radius) {
super();
this.radius = radius;
}
yuzasi() { // ← qayta yozildi (override)
return Math.PI * this.radius ** 2;
}
}
const kvadrat = new Kvadrat(5);
const doira = new Doira(3);
kvadrat.tavsif(); // "Yuzasi: 25"
doira.tavsif(); // "Yuzasi: 28.27..."
tavsif() metodini bir marta yozdik — barcha shakllarga ishladi. Har bir shakl o'z yuzasi() ni biladi. Bu — polimorfizm.
instanceof zanjirda
const menejer = new Menejer("Vali", 10_000_000, 8);
console.log(menejer instanceof Menejer); // true
console.log(menejer instanceof Xodim); // true ← meros zanjiri
console.log(menejer instanceof Object); // true ← hammasi Object dan
Tez-tez uchraydigan xatolar
super() ni constructor boshida chaqirmaslik:
class Bola extends Ota {
constructor(ism) {
this.qoshimcha = true; // ❌ ReferenceError: Must call super constructor before using 'this'
super(ism);
}
}
class Bola extends Ota {
constructor(ism) {
super(ism); // ✅ avval super
this.qoshimcha = true;
}
}
Sababi: extends bilan this faqat super() chaqirilgandan keyin mavjud bo'ladi. super() — ota class ning konstruktori, u this ni yaratadi.
Ota metodini override qilib, super ni unutish:
class Hayvon {
ovqatlantirish() {
this.toq = true;
console.log("Ovqatlandi");
}
}
class It extends Hayvon {
ovqatlantirish() {
// ❌ super.ovqatlantirish() unutildi
// this.toq = true qilinmadi!
console.log("It ovqatlandi");
}
}
class It extends Hayvon {
ovqatlantirish() {
super.ovqatlantirish(); // ✅ ota logikasi ham ishladi
console.log("It xursand bo'ldi");
}
}
Juda chuqur meros zanjiri:
// ❌ — o'qish va debug qiyin
class A extends B {}
class B extends C {}
class C extends D {}
class D extends E {}
Amalda 2-3 daraja yetarli. Undan chuqurroq bo'lsa — composition (composition over inheritance) ko'rib chiqing.
Xulosa
extends — bola class ota classning barcha xususiyat va metodlarini meros oladi.
super() — ota konstruktorini chaqiradi. extends li har bir constructorda birinchi qatorda bo'lishi shart.
super.metod() — ota classning metodini chaqiradi. Override qilingan metodda ota logikasini saqlab qolish uchun.
Override — ota metodini bola classda qayta yozish. Polimorfizm — bir xil interfeys, har xil xulq.
Xodim ← bazaviy class
└── Menejer ← extends Xodim, super(ism, maosh)
└── Direktor ← extends Menejer, super(ism, maosh, jamoa)
Keyingi dars
31-dars: Class — static, getter, setter