Class — extends va super

~20 daq · JavaScript · OOP

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