2.10-bob: OOP — class, inheritance, encapsulation, polymorphism, static
2-QISM — JavaScript (0 dan chuqurgacha) · 10-mavzu
1. Kirish va motivatsiya
2.5-bobda JS obyekt tizimining ildizini (prototype, this) xom holda ko'rdik — va u biroz "qo'l ishi" edi. Endi uning chiroyli, zamonaviy yuzasi — class sintaksisi va to'liq OOP (Object-Oriented Programming — obyektga yo'naltirilgan dasturlash) ni o'rganamiz.
OOP — katta dasturlarni real dunyo obyektlari sifatida modellashtirish usuli: User, Mahsulot, Buyurtma — har biri o'z ma'lumoti (xususiyat) va xulqi (metod) bilan. Bu — kodni tartibli, qayta ishlatiladigan va kengaytiriladigan qiladi.
O'xshatish:
class— bu chizma (blueprint),newbilan yaratilgan obyekt — bino. Bitta chizmadan minglab bino qurish mumkin — har biri alohida, lekin bir xil tuzilishda.Userclass'idan minglab foydalanuvchi obyekti.
OOP — NestJS (8-QISM) ning butun asosi, TypeScript (7) bilan kuchayadi, va Design Patterns 9.2-bob, SOLID 9.1-bob ning poydevori. Bu bob — katta loyiha arxitekturasining bir ustuni.
2. Nazariya — chuqur tushuntirish
2.1. class — asoslar
class — obyektlar yaratish uchun "chizma". Aslida u prototype 2.5-bob ustiga qurilgan syntactic sugar (chiroyli yuza) — lekin yozish ancha oson:
class User {
// constructor — obyekt YARATILGANDA bir marta ishlaydi
constructor(ism, yosh) {
this.ism = ism; // this — yangi yaratilayotgan obyekt (2.5)
this.yosh = yosh;
}
// metod (prototype'da yashaydi — barcha obyektlar ulashadi, 2.5)
salomla() {
return `Salom, men ${this.ism}`;
}
}
const ali = new User("Ali", 19); // new — yangi obyekt (2.5)
ali.salomla(); // "Salom, men Ali"
ali.yosh; // 19new User(...) constructor chaqiriladi this yangi obyektga ishora qiladi (2.5: new binding) obyekt qaytadi.
2.2. OOP ning 4 ustuni
OOP to'rt asosiy prinsipga tayanadi. Ularni bilish — intervyu va arxitektura uchun zarur:
| Ustun | Ma'nosi |
|---|---|
| Encapsulation (inkapsulyatsiya) | ma'lumotni yashirish, faqat metod orqali murojaat |
| Inheritance (meros) | bir class'ni boshqasidan kengaytirish |
| Polymorphism (polimorfizm) | bir metod har class'da har xil ishlashi |
| Abstraction (mavhumlashtirish) | murakkablikni yashirib, sodda interfeys (0.6) |
Quyida har birini ko'ramiz.
2.3. Encapsulation va private (#) maydonlar
Encapsulation — ichki ma'lumotni yashirib, faqat ruxsat etilgan metodlar orqali murojaat (2.4-closure'dagi private g'oyasi). JS'da # (hash) bilan private maydon:
class BankHisob {
#balans = 0; // PRIVATE — faqat class ICHIDA ko'rinadi
constructor(boshlangich) {
this.#balans = boshlangich;
}
qoy(summa) {
if (summa <= 0) return "Noto'g'ri summa";
this.#balans += summa;
}
yech(summa) {
if (summa > this.#balans) return "Mablag' yetarli emas"; // himoya
this.#balans -= summa;
}
get balans() { return this.#balans; } // getter orqali o'qish (2.5)
}
const hisob = new BankHisob(100);
hisob.qoy(50);
console.log(hisob.balans); // 150
// console.log(hisob.#balans); // SyntaxError — tashqaridan ko'rinmaydi!Nega private?
#balansni faqat class metodlari o'zgartiradi (tekshiruv bilan). Tashqaridan to'g'ridan-to'g'rihisob.#balans = -1000qilib bo'lmaydi — ma'lumot himoyalangan. Bu — ishonchli kodning asosi.
2.4. Getter va Setter
Getter/Setter — xususiyatga o'xshab ishlatiladigan, lekin orqasida mantiq bo'lgan metodlar:
class Doira {
#radius;
constructor(radius) { this.#radius = radius; }
get yuza() { // get — () siz, xususiyat kabi o'qiladi
return Math.PI * this.#radius ** 2;
}
get radius() { return this.#radius; }
set radius(qiymat) { // set — tayinlashda mantiq + tekshiruv
if (qiymat <= 0) throw new Error("Radius musbat bo'lsin");
this.#radius = qiymat;
}
}
const d = new Doira(5);
console.log(d.yuza); // 78.54 — () SIZ! (getter — xususiyat kabi)
d.radius = 10; // setter ishlaydi (tekshiruv bilan)
// d.radius = -5; // Error (setter himoyasi)2.5. Inheritance — extends va super
Inheritance — bir class boshqasidan meros olib, uni kengaytiradi (2.5-prototypal inheritance'ning chiroyli usuli):
class Hayvon {
constructor(nom) { this.nom = nom; }
nafasOl() { return `${this.nom} nafas olyapti`; }
ovoz() { return "..."; }
}
class It extends Hayvon { // It — Hayvon'dan meros
constructor(nom, zot) {
super(nom); // ota constructor'ni chaqir (super — MDN)
this.zot = zot; // super'dan KEYIN this ishlatiladi
}
ovoz() { return `${this.nom}: Vov!`; } // metodni qayta yozish (override)
}
const akbar = new It("Akbar", "Alabay");
akbar.nafasOl(); // "Akbar nafas olyapti" (Hayvon'dan meros)
akbar.ovoz(); // "Akbar: Vov!" (It'ning o'zi — override)
super— ota class constructor'i/metodini chaqiradi. Subclass constructor'idathisdan oldinsuper()chaqirilishi shart (aks holda xato).
instanceof — obyekt qaysi class'dan (yoki uning otasidan) ekanini tekshiradi. Meros zanjiri bo'ylab ishlaydi:
akbar instanceof It; // true — bevosita o'z class'i
akbar instanceof Hayvon; // true — ota class ham (meros zanjiri)
akbar instanceof Mushuk; // false — boshqa shox
akbar instanceof Object; // true — hammasi Object'dan meros (2.5)Qachon kerak: turli class obyektlari bir massivda bo'lsa va turiga qarab ish qilmoqchi bo'lganda (
if (x instanceof Doira) ...). Lekin ko'pinstanceof— polimorfizm 2.6-bob bilan almashtirilsa, kod toza bo'ladi 9.1-bob.
2.6. Polymorphism — bir metod, har xil xulq
Polymorphism — bir xil nomli metod har class'da har xil ishlashi. Yuqorida ovoz() — Hayvon, It, Mushukda har xil:
class Mushuk extends Hayvon {
ovoz() { return `${this.nom}: Miyov!`; }
}
const hayvonlar = [new It("Akbar"), new Mushuk("Mosi")];
// Bir xil chaqiriq — har xil natija (polimorfizm)
hayvonlar.forEach(h => console.log(h.ovoz()));
// "Akbar: Vov!" "Mosi: Miyov!"Nega kuchli: kod
h.ovoz()deydi — qaysi hayvon ekanini bilmasdan. Har class o'z xulqini beradi. Yangi hayvon qo'shsangiz, mavjud kodni o'zgartirmaysiz (9.1: Open/Closed).
2.7. Static — class'ning o'ziga tegishli
static metod/maydon — obyektga emas, class'ning o'ziga tegishli; obyekt yaratmasdan chaqiriladi:
class MathUtil {
static PI = 3.14159;
static kvadrat(n) { return n * n; } // static metod
}
MathUtil.kvadrat(5); // 25 — obyekt YARATMASDAN, class orqali
MathUtil.PI; // 3.14159
// new MathUtil().kvadrat() — ishlamaydi (static — obyektda emas)
// Klassik misol — factory yoki utility
class User {
constructor(ism) { this.ism = ism; }
static yaratMehmon() { return new User("Mehmon"); } // factory (9.2)
}
const mehmon = User.yaratMehmon();Qachon static: utility funksiyalar (
Math.maxham static), factory metodlar, hisoblagichlar (umumiy holat) — obyektga bog'liq bo'lmagan narsalar.
Static blok (static { ... }) — static maydonlarni murakkab mantiq bilan bir marta (class yuklanganda) tayyorlash uchun (MDN, ES2022):
class Konfig {
static manbalar;
static { // class e'lon qilinganda BIR marta ishlaydi
const xom = ["db", "cache", "log"];
Konfig.manbalar = xom.map(m => m.toUpperCase());
}
}
Konfig.manbalar; // ["DB", "CACHE", "LOG"]Nega kerak: oddiy
static x = ...bitta ifoda bilan cheklangan; static blokda bir nechta qator,try/catch, sikl ishlatib, static holatni to'liq sozlash mumkin.
2.8. class aslida prototype (2.5 bilan bog'lanish)
Eslatma: class — yangi narsa emas, balki prototype 2.5-bob ning chiroyli yozuvi:
class User { salomla() {} }
// aslida ≈
function User() {}
User.prototype.salomla = function() {};Metodlar prototypeda (barcha obyektlar ulashadi — 2.5, xotira tejash); this — har bir obyekt. Shuning uchun 2.5-bobni tushunish — classni chuqur tushunish demak.
3. Sintaksis — tez ma'lumotnoma
class Nom extends Ota {
#private = 0; // private maydon (2.3)
static umumiy = 0; // static maydon (2.7)
constructor(p) {
super(p); // ota constructor (meros — 2.5)
this.x = p;
}
metod() {} // oddiy metod (prototype'da)
get xususiyat() {} // getter (2.4)
set xususiyat(v) {} // setter (2.4)
static yordam() {} // static metod (2.7)
static { /* ... */ } // static blok — bir marta sozlash (2.7)
}
const obj = new Nom(arg); // obyekt yaratish
obj instanceof Nom; // turini tekshirish — true (2.5)4. Batafsil kod namunalari
Misol 1 — To'liq class (encapsulation + getter/setter)
class Mahsulot {
#narx; // private (2.3)
constructor(nom, narx) {
this.nom = nom;
this.#narx = narx;
}
get narx() { return this.#narx; } // getter (2.4)
set narx(yangi) { // setter + tekshiruv
if (yangi < 0) throw new Error("Narx manfiy bo'lmasin");
this.#narx = yangi;
}
get narxFormat() { // hisoblangan getter
return `${this.#narx.toLocaleString("uz")} so'm`; // (2.6)
}
chegirma(foiz) { this.#narx *= (1 - foiz / 100); }
}
const olma = new Mahsulot("Olma", 12000);
console.log(olma.narxFormat); // "12 000 so'm"
olma.chegirma(25);
console.log(olma.narx); // 9000Misol 2 — Inheritance va polymorphism (2.5, 2.6)
class Shakl {
constructor(nom) { this.nom = nom; }
yuza() { return 0; } // bola override qiladi
tasvir() { return `${this.nom}: yuza = ${this.yuza().toFixed(2)}`; }
}
class Doira extends Shakl {
constructor(r) { super("Doira"); this.r = r; }
yuza() { return Math.PI * this.r ** 2; } // override (2.6)
}
class Kvadrat extends Shakl {
constructor(t) { super("Kvadrat"); this.t = t; }
yuza() { return this.t ** 2; }
}
const shakllar = [new Doira(5), new Kvadrat(4)];
shakllar.forEach(s => console.log(s.tasvir())); // polimorfizm (2.6)
// "Doira: yuza = 78.54" "Kvadrat: yuza = 16.00"Misol 3 — Static (factory va hisoblagich) (2.7)
class User {
static soni = 0; // umumiy hisoblagich (static)
#id;
constructor(ism) {
this.ism = ism;
this.#id = ++User.soni; // har obyektga noyob id
}
get id() { return this.#id; }
static yaratAdmin(ism) { // factory metod (9.2)
const u = new User(ism);
u.admin = true;
return u;
}
}
const a = new User("Ali");
const v = User.yaratAdmin("Vali");
console.log(a.id, v.id); // 1 2
console.log(User.soni); // 2 (umumiy)Misol 4 — Meros zanjiri (super metod chaqiruvi)
class Hayvon {
constructor(nom) { this.nom = nom; }
tasvir() { return `Bu ${this.nom}`; }
}
class It extends Hayvon {
tasvir() {
// ota metodini chaqirib, kengaytirish (super — 2.5)
return `${super.tasvir()}, u it`;
}
}
console.log(new It("Akbar").tasvir()); // "Bu Akbar, u it"5. To'g'ri va noto'g'ri holatlar
1) Subclass constructor'ida super()ni unutish
// ReferenceError — super'dan oldin this (2.5)
class It extends Hayvon {
constructor(nom) { this.nom = nom; } // super() yo'q!
}
// avval super()
class It extends Hayvon {
constructor(nom) { super(nom); this.zot = "..."; }
}2) Ma'lumotni public qoldirish (private o'rniga)
// tashqaridan buzilishi mumkin (2.3)
class Hisob { constructor(b) { this.balans = b; } }
hisob.balans = -99999; // hech qanday himoya yo'q!
// private + metod
class Hisob { #balans; /* faqat metod orqali */ }3) Getter'ni () bilan chaqirish
// getter — xususiyat kabi, () SIZ (2.4)
d.yuza(); // TypeError (yuza — son, funksiya emas)
//
d.yuza;4) Hamma narsani class qilish
// oddiy ma'lumot/funksiya uchun keraksiz class
class Yordamchi { static qosh(a, b) { return a + b; } }
// oddiy funksiya yetadi (2.3)
const qosh = (a, b) => a + b;6. Keng tarqalgan xatolar va yechimlari
Xato 1 — Must call super constructor before accessing 'this'
Sababi: subclass constructor'ida thisdan oldin super() chaqirilmadi 2.5-bob. Yechimi: constructorning birinchi qatorida super(...).
Xato 2 — Cannot read private member #x
Sababi: private maydonga class tashqarisidan murojaat 2.3-bob. Yechimi: getter/metod orqali; faqat class ichida #.
Xato 3 — TypeError: X is not a constructor
Sababi: newsiz class chaqirildi yoki static metodni obyektda. Yechimi: obyekt — new Class(); static — Class.metod().
Xato 4 — Metod this yo'qotadi (callback'da)
setTimeout(obj.metod, 1000); // this yo'qoladi (2.5)Sababi: metod ajratilganda this bog'lanishi yo'qoladi 2.5-bob. Yechimi: arrow bilan o'ra (() => obj.metod()) yoki bind 2.5-bob.
Xato 5 — Chuqur meros zanjiri (murakkablik)
Sababi: 4-5 daraja meros — chalkash, mo'rt. Yechimi: "composition over inheritance" — meros o'rniga obyektlarni birlashtirish (9.1, 9.3); meros faqat haqiqiy "is-a" munosabatda.
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- Prototype 2.5-bob:
class— prototype ustiga sugar;this, meros mexanizmi. - TypeScript (7):
class+ tip;interface,implements,abstract— OOP kuchayadi. - NestJS (8): butun framework class asosida (controller, service, module — DI).
- Design Patterns 9.2-bob: Singleton, Factory (Misol 3), Observer — class bilan.
- SOLID 9.1-bob: Single Responsibility, Open/Closed (polimorfizm — 2.6).
- React (eski): class komponentlar (hozir function — 11.2, lekin uchraydi).
- DB ORM (6.11–6.13): entity'lar — class (TypeORM, Prisma model).
8. Eng yaxshi amaliyotlar (best practices)
- Ma'lumotni private (
#) qiling, metod orqali murojaat — encapsulation 2.3-bob. - Getter/setter bilan tekshiruvli murojaat 2.4-bob; getter —
()siz. - Subclass constructor'ida birinchi
super()2.5-bob. - Polimorfizm bilan
if/switcho'rniga — har class o'z xulqini beradi (2.6, 9.1). - "Composition over inheritance" — chuqur meros o'rniga birlashtirish (6-bo'lim, 9.3).
- Static — utility/factory uchun 2.7-bob; obyektga bog'liq bo'lmaganda.
- Hamma narsani class qilmang — oddiy ma'lumot/funksiya yetsa, undan foydalaning (5-bo'lim).
- Bitta class — bitta mas'uliyat (Single Responsibility — 9.1).
9. Amaliy loyiha: "Kutubxona Boshqaruv Tizimi (OOP)"
OOP ning 4 ustunini to'liq ishlatadigan tizim.
Maqsad
class, encapsulation (private), getter/setter, inheritance, polymorphism va static'ni amalda qo'llab, real domenni OOP bilan modellashtirish.
Talablar (requirements)
Kitobclass:nom,muallif, private#band(band/bo'sh holat);band()/qaytar()metodlari;holatgetter (2.3, 2.4).- Meros:
KitobdanElektronKitob(qo'shimchaformat) vaAudioKitob(qo'shimchadavomiylik) —superbilan 2.5-bob. - Polymorphism: har class'da
tasvir()metodi har xil 2.6-bob; ro'yxat bo'ylab bir xil chaqiruv (Misol 2). Foydalanuvchiclass: private#olinganKitoblarmassivi;ol(kitob)/qaytar(kitob)(tekshiruv bilan — encapsulation).- Static:
Kitob.sonihisoblagich (har yaratilganda oshadi);Kitob.yaratNamuna()factory (2.7, Misol 3). - Getter/setter: kamida bitta tekshiruvli setter (masalan reyting 1–5 oralig'i) 2.4-bob.
- Himoya isboti: private maydonga tashqaridan murojaat qilib bo'lmasligini ko'rsating 2.3-bob.
- (Bonus)
Kutubxonaclass — kitoblar to'plami;qidir,bandlar,bo'shlar(Array metodlari — 2.7).
Maslahatlar (hint)
- Private:
#band = false;— faqat metod ichida o'zgartiring. - Meros:
class ElektronKitob extends Kitob { constructor(...) { super(...); ... } }2.5-bob. - Polimorfizm: har class
tasvir()ni override qilsin;kitoblar.forEach(k => k.tasvir())2.6-bob. - Static hisoblagich:
static soni = 0;constructor'daKitob.soni++(Misol 3). - Setter tekshiruvi:
set reyting(v) { if (v<1||v>5) throw...; }2.4-bob.
"Tayyor" mezonlari (acceptance criteria)
-
Kitobclass private maydon va getter/setter bilan. - Meros (
extends+super) ishlaydi. - Polimorfizm:
tasvir()har class'da har xil, bir xil chaqiruv. - Encapsulation: band holat faqat metod orqali o'zgaradi.
- Static hisoblagich va factory ishlaydi.
- Tekshiruvli setter mavjud.
- Private maydon tashqaridan ko'rinmasligi isbotlangan.
Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.
10. Xulosa va keyingi bobga ko'prik
Bu bobda OOP va class ni o'rgandik:
class— prototype 2.5-bob ustiga chiroyli yuza;constructor(newda ishlaydi), metodlar (prototype'da),this— obyekt.- 4 ustun: encapsulation (private
#, metod orqali), inheritance (extends/super), polymorphism (override — bir metod, har xil xulq), abstraction. - Getter/setter — xususiyat kabi, lekin mantiq/tekshiruv bilan (
()siz). static— class'ning o'ziga tegishli (utility, factory, hisoblagich);static { }blok bilan bir marta sozlash.instanceof— obyekt qaysi class'dan ekanini meros zanjiri bo'ylab tekshiradi 2.5-bob.- Best: private bilan himoya, polimorfizm bilan
ifo'rniga, "composition over inheritance".
Keyingi bob — 2.11-bob: Asinxron JS — callback, Promise, async/await, fetch. Bu — JS'ning eng muhim va eng ko'p so'raladigan mavzularidan biri. 0.5-bobda ko'rgan event loop, 0.4-dagi so'rovlar — hammasi shu yerda birlashadi. Tarmoqdan ma'lumot olish, fayl o'qish, kutish — bularning hammasi asinxron. Promise va async/awaitsiz zamonaviy JS yo'q.
Foydalanilgan rasmiy/ishonchli manbalar
- MDN Web Docs — Classes, constructor,
extends/super, static - MDN Web Docs — Private elements (
#), private class fields - MDN Web Docs — getter/setter, Using classes
- MDN Web Docs —
instanceof, static initialization blocks
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!