Boshqa har qanday OOP tillari singari, Python ham klass inheritance tushunchasini qo’llab-quvvatlaydi.
Inheritance bizga mavjud klassdan yangi klass yaratish imkonini beradi.
Yaratilgan yangi klass quyi klass (bola yoki hosila klass) deb nomlanadi va bolalar klassi olingan mavjud klass superklass (ota yoki asosiy klass) deb nomlanadi.
Python Inheritance sintaksisi:
Mana Pythondagi Inheritancening sintaksisi,
# superklassni e'lon qilish
class super_class:
# atribut va metod yaratish
# inheritance
class sub_class(super_class):
# super_classning atribut va metodlari
# sub_classning atribut va metodlari
Bu erda biz sub_class klassini super_class klassidan meros qilib olamiz.
1-misol. Python Inheritance:
class Animal:
# ota klassning atribut va metodlari
name = ""
def eat(self):
print("I can eat")
# Animal superklassidan meros olish
class Dog(Animal):
# subklassdagi yangi metod
def display(self):
# selfdan foydalanib superklassning name nomli atributiga kirish
print("My name is ", self.name)
# subklassdan ob'ekt yaratish
labrador = Dog()
# superklassning atribut va metodlariga kirish
labrador.name = "Reks"
labrador.eat()
# subklass metodini chaqirish
labrador.display()
Natija:
I can eat
My name is Reks
Yuqoridagi misolda biz “Animal” super klassidan “Dog” bola klassini oldik. Statementlarga e’tibor bering,
labrador.name = "Reks"
labrador.eat()
Bu yerda biz Animal klassining nomi va eat() ga kirish uchun labrador (It ob’ekti) dan foydalanamiz. Bu mumkin, chunki quyi klass yuqori klassning barcha atributlari va metodlarini meros qilib oladi.
Bundan tashqari, biz selfdan foydalanib Dog klassining metodi ichidagi name atributiga kirdik.
Pythonda meros – bu munosabatdir. Ya’ni, biz merosdan faqat ikkita klass o’rtasida o’zaro bog’liqlik mavjud bo’lganda foydalanamiz. Masalan,
Avtomobil – bu transport vositasi
Olma – bu meva
Mushuk – Hayvon
Bu yerda, Avtomobil Avtomobildan, Apple Fruitdan meros bo’lishi mumkin va hokazo.
2-misol. Pythonda inheritance:
Keling, Pythondagi merosning yana bir misolini ko’rib chiqaylik,
Ko’pburchak – bu 3 yoki undan ortiq tomonlari bo’lgan yopiq figura. Aytaylik, bizda ko’pburchak deb nomlangan klass mavjud bo’lib, u quyidagicha aniqlanadi:
class Polygon:
def __init__(self, no_of_sides):
self.n = no_of_sides
self.sides = [0 for i in range(no_of_sides)]
def inputSides(self):
self.sides = [float(input("Enter side "+str(i+1)+" : ")) for i in range(self.n)]
def dispSides(self):
for i in range(self.n):
print("Side",i+1,"is",self.sides[i])
Bu klassda n tomonlar sonini va har bir tomonning kattaligini sides deb ataladigan ro’yxat sifatida saqlash uchun ma’lumotlar atributlari mavjud.
- inputSides() metodi har bir tomonning kattaligini oladi
- dispSides() metodi bu yon uzunliklarni ko’rsatadi
Uchburchak – bu 3 tomoni bo’lgan ko’pburchak. Shunday qilib, biz Polygondan meros bo’lgan Triangle nomli klassni yaratishimiz mumkin. Bu Polygon klassining barcha atributlarini Triangle klassi uchun mavjud qiladi.
Biz ularni yana qaytadan yaratishimiz shart emas (kodni qayta ishlatish imkoniyati mavjud). Uchburchakni quyidagicha yaratilishi mumkin.
class Triangle(Polygon):
def __init__(self):
Polygon.__init__(self,3)
def findArea(self):
a, b, c = self.sides
# perimetrnining yarmini hisoblash
s = (a + b + c) / 2
area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
print('The area of the triangle is %0.2f' %area)
Biroq, Triangle klassida uchburchak maydonini topish va chop etish uchun findArea() nomli yangi metodi mavjud.
Keling, yuqoridagi misolning to’liq kodini ko’rib chiqaylik, shu jumladan ob’ekt yaratishni ham,
class Polygon:
# Tomonlar miqdorini belgilash
def __init__(self, no_of_sides):
self.n = no_of_sides
self.sides = [0 for i in range(no_of_sides)]
def inputSides(self):
self.sides = [float(input("Enter side "+str(i+1)+" : ")) for i in range(self.n)]
# ko'pburchakning har bir tomoni uzunligini ko'rsatuvchi metod
def dispSides(self):
for i in range(self.n):
print("Side",i+1,"is",self.sides[i])
class Triangle(Polygon):
# Polygon sinfining __init__ metodini chaqirish orqali
# Uchburchak tomonlari sonini 3 deb belgilash
def __init__(self):
Polygon.__init__(self,3)
def findArea(self):
a, b, c = self.sides
# perimetrnining yarmini hisoblash
s = (a + b + c) / 2
# Uchburchakning maydonini hisoblash uchun
# Heron formulasidan foydalanish
area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
print('The area of the triangle is %0.2f' %area)
# Triangle klassining namunasini yaratish
t = Triangle()
# Foydalanuvchiga uchburchakning tomonlarini kiritishni taklif qilish
t.inputSides()
# Uchburchakning tomonlarini ko'rsatish
t.dispSides()
# Uchburchak maydonini hisoblash va chop etish
t.findArea()
Natija:
Enter side 1 : 3
Enter side 2 : 5
Enter side 3 : 4
Side 1 is 3.0
Side 2 is 5.0
Side 3 is 4.0
The area of the triangle is 6.00
Bu yerda biz Triangle klassi uchun inputSides() yoki dispSides() kabi metodlarni alohida belgilamagan bo’lsak ham, ulardan foydalana olganimizni ko’rishimiz mumkin.
Agar atribut klassning o’zida topilmasa, qidiruv asosiy klassga davom etadi. Agar asosiy klassning o’zi boshqa klasslardan olingan bo’lsa, bu rekursiv takrorlanadi.
Python inheritanceda metodni qayta yozish:
Oldingi misolda biz quyi klass ob’ekti superklass metodiga kirishi mumkinligini ko’rib o’tdik.
Ammo, agar bir xil usul superklassda ham, bola klassda ham mavjud bo’lsa-chi?
Bunday holda, bola klassdagi metod yuqori klassdagi metodni bekor qiladi. Ushbu konsepsiya Pythonda method overriding (metodni qayta yozish) deb nomlanadi.
Method overriding:
class Animal:
# ota klassning atributi va metodi
name = ""
def eat(self):
print("I can eat")
# Animal nomli ota klassdan meros olish
class Dog(Animal):
# eat() metodini qayta yozish
def eat(self):
print("I like to eat bones")
# bola klass obyektini yaratish
labrador = Dog()
# labrador ob'ektining eat() metodini chaqirish
labrador.eat()
Natija:
I like to eat bones
Yuqoridagi misolda bir xil eat() usuli Dog klassida ham, Animal klassida ham mavjud.
Endi Dog kichik klassi ob’ekti yordamida eat() metodini chaqirganimizda, Dog klassining metodi chaqiriladi.
Buning sababi, Dog kichik klassining eat() metodi Animal superklassining bir xil nomdagi metodini bekor qiladi.
Python inheritanceda Super() metodi:
Ilgari biz quyi klassdagi bir xil metod superklassdagi metodni bekor qilishini ko’rdik.
Biroq, agar biz quyi klassdan superklass metodiga kirishimiz kerak bo’lsa, biz super() metodidan foydalanamiz. Masalan,
class Animal:
name = ""
def eat(self):
print("I can eat")
# Animal nomli ota klassdan meros olish
class Dog(Animal):
# eat() metodini qayta yozish
def eat(self):
# super() yordamida superklassning eat() metodini chaqirish
super().eat()
print("I like to eat bones")
# bola klass obyektini yaratish
labrador = Dog()
labrador.eat()
Natija:
I can eat
I like to eat bones
Yuqoridagi misolda Dog kichik klassining eat() metodi Animal superklassining bir xil metodini bekor qiladi.
Dog kichik klassidan Animal superklassining eat() metodini chaqirish uchun biz quyidagi super() metodidan foydalanganmiz.
# superklassning eat() metodini chaqirish
super().eat()
Shunday qilib, biz labrador ob’ekti yordamida eat() usulini chaqirganimizda eat() usulining qayta yozilgan varianti bilan birga superklassdagi varianti ham bajariladi.
# eat() metodini chaqirish
labrador.eat()
Inheritance (Meros)dan foydalanish:
- Bola klass ota klassining barcha funksiyalarini meros qilib olishi mumkinligi sababli, bu kodni qayta ishlatish imkonini beradi.
- Funksionallik ishlab chiqilgandan so’ng, uni oddiygina meros qilib olishingiz mumkin. G’ildirakni qayta ixtiro qilishning hojati yo’q. Bu toza kodni va uni saqlashni osonlashtiradi.
- Siz Bola klassga o’zingizning funksiyalaringizni ham qo’shishingiz mumkinligi sababli, siz faqat foydali funksiyalarni meros qilib olishingiz va boshqa kerakli xususiyatlarni belgilashingiz mumkin.