Inheritance — yangi class mavjud classning xususiyat va xatti-harakatlarini qabul qilib, ularni kengaytirishi yoki ayrim qismini o‘zgartirishi mumkin bo‘lgan object-oriented mexanizm.
Mavjud class base, parent yoki superclass, yangi class esa derived, child yoki subclass deb ataladi.
Inheritance code reuse bilan birga type relationship yaratadi.
Is-a munosabati
Inheritance semantik jihatdan is-a munosabatini ifodalashi kerak.
Masalan:
Dog is an Animal
Agar child object parent kutilgan joyda mantiqan ishlay olmasa, inheritance noto‘g‘ri tanlangan bo‘lishi mumkin.
Faqat bir nechta methodni qayta ishlatish uchun inheritance yaratish kuchli coupling keltiradi.
Base class
Base class umumiy:
- field;
- method;
- invariant;
- lifecycle;
- protected helper
berishi mumkin.
Child class yangi method qo‘shadi yoki virtual methodni override qiladi.
Method overriding
Child class parent methodining o‘z implementationini beradi.
Shape.area()
Circle.area()
Rectangle.area()
Caller Shape type orqali ishlasa ham, runtime haqiqiy object methodini chaqiradi.
Bu runtime polymorphismning asosidir.
Override va overload
Override — child parentdagi bir xil contract methodini almashtiradi.
Overload — bir scope’da bir xil nomli, ammo parameterlari boshqa methodlar.
Ikki tushuncha bir xil emas.
Til override kalit so‘zi orqali xatoni compile vaqtida aniqlashi mumkin.
Access modifier
Parent memberlar:
- public;
- protected;
- private
bo‘lishi mumkin.
Protected member child classga ochiq, tashqi kodga yopiq.
Ko‘p protected state childni parent implementationiga qattiq bog‘laydi.
Private state methodlar orqali boshqarilganda invariant yaxshiroq saqlanadi.
Constructor
Child object yaratilganda base class constructori ham bajariladi.
Tartib odatda:
Base constructor virtual method chaqirsa, child state hali tayyor bo‘lmasligi mumkin.
Shu sababli constructor ichida overridable method chaqirish xavfli.
Single inheritance
Class faqat bitta bevosita base classga ega.
Afzalligi:
- hierarchy sodda;
- method resolution aniq;
- diamond muammosi kam.
Java classlari kabi tizimlarda class uchun single inheritance, interface uchun multiple inheritance qo‘llanishi mumkin.
Multiple inheritance
Class bir nechta base classdan meros oladi.
Afzalligi — bir nechta behaviorni birlashtirish.
Kamchiligi:
- bir xil member nomi;
- state takrorlanishi;
- constructor tartibi;
- method resolution;
- diamond problem.
Til aniq MRO yoki virtual inheritance qoidalarini belgilaydi.
Diamond problem
A va B bir base classdan meros oladi. C esa A va Bdan meros oladi.
Base
/ \
A B
\ /
C
C ichida Base state’i bitta yoki ikkita nusxa bo‘lishi mumkin.
Method qaysi yo‘ldan olinishi ham noaniq.
Method Resolution Order
Multiple inheritance tizimida method qidirish tartibi MRO bilan belgilanadi.
Runtime class hierarchy’ni ma’lum algoritm bilan tekshiradi.
MROni tushunmasdan mixinlar kombinatsiyasi kutilmagan methodni chaqirishi mumkin.
Abstract base class
Abstract base class umumiy contract va qisman implementation beradi.
Unda abstract methodlar bo‘lishi mumkin.
Child class ularni implementatsiya qilmaguncha concrete object yaratilmaydi.
Final class va method
Ba’zi til class yoki methodni meros olish va override qilishni taqiqlaydi.
final:
- invariantni saqlaydi;
- security behaviorni o‘zgartirishni cheklaydi;
- optimizationga yordam beradi;
- API extension nuqtasini aniq qiladi.
Liskov substitution
Child object parent type kutilgan joyda contractni buzmasdan ishlashi kerak.
Child:
- kuchliroq precondition talab qilmasligi;
- zaifroq postcondition bermasligi;
- parent invariantini buzmasligi;
- kutilmagan exception semantikasini qo‘shmasligi
kerak.
Bu Liskov Substitution Principle bilan bog‘liq.
Fragile base class
Base class implementationi o‘zgarganda child classlar kutilmagan tarzda buzilishi mumkin.
Sabablar:
- protected field;
- virtual method chaqirish tartibi;
- ichki method override qilingan;
- yangi method nomi conflict;
- constructor behavior.
Public inheritance API uzoq muddatli contractga aylanadi.
Composition
Composition object ichida boshqa objectni saqlab, uning xizmatidan foydalanadi.
Car has an Engine
Inheritance:
Dog is an Animal
Composition ko‘pincha:
- couplingni kamaytiradi;
- implementationni runtime’da almashtiradi;
- kichik componentlarni birlashtiradi;
- hierarchy chuqurligini kamaytiradi.
“Composition over inheritance” barcha inheritance noto‘g‘ri degani emas.
Mixin va trait
Mixin yoki trait state yoki behaviorning kichik qismini bir nechta classga qo‘shadi.
U to‘liq “is-a” hierarchy yaratmasligi mumkin.
Conflict va method resolution til qoidalariga bog‘liq.
Sealed hierarchy
Sealed class qaysi child type’lar ruxsat etilganini cheklaydi.
Compiler barcha variantlarni bilib:
berishi mumkin.
ORM inheritance
Object inheritance database tablelarga turli usulda map qilinadi:
Har strategiyaning query, null field va migration oqibatlari bor.
Object hierarchy database uchun tabiiy model bo‘lavermaydi.
Serialization
Base reference orqali child object serialize qilinganda type discriminator kerak bo‘lishi mumkin.
Client qaysi subtype kelishini bilishi kerak.
Yangi subtype qo‘shish public schema compatibility’ga ta’sir qiladi.
Test
Base class contract testlari barcha child implementationlarga qo‘llanishi mumkin.
Bu substitution talablarini tekshiradi.
Faqat childning ichki methodini emas, parent contract ostidagi xatti-harakatini test qilish muhim.
Diagnostika
Inheritance muammosida:
- hierarchy;
- MRO;
- override;
- constructor tartibi;
- protected state;
- base contract;
- subtype exception;
- serialization;
- fragile base;
- composition imkoniyati
tekshiriladi.
Kutilmagan method chaqirilsa, runtime type va method resolution tartibi aniqlanadi.
Bog‘liq tushunchalar
Object-oriented programming, Base class, Subclass, Method overriding, Polymorphism, Abstract class, Liskov substitution, Composition, Mixin, MRO