Өвлөлт (Inheritance)
Өмнөх хичээлд класс үүсгэж, объект ажиллуулж сурлаа. Гэхдээ ижил төстэй хэд хэдэн класс байвал нэг кодыг дахин дахин бичих хэрэг гардаг. Өвлөлт нь энэ асуудлыг шийдэнэ — нэг классын бүх зүйлийг нөгөө класс өвлөн авч, зөвхөн ялгаатай хэсгийг нэмж бичнэ.
Өвлөлтийн үндэс
Өвлүүлж буй классыг parent class (эцэг класс), өвлөн авч буй классыг child class (хүү класс) гэнэ.
# Parent class
class Амьтан:
def __init__(self, нэр: str, нас: int) -> None:
self.нэр = нэр
self.нас = нас
def мэдээлэл(self) -> str:
return f"{self.нэр}, {self.нас} настай"
def дуу_гаргах(self) -> str:
return "..."
# Child class — Амьтан классыг өвлөнө
class Нохой(Амьтан):
def дуу_гаргах(self) -> str: # parent-ийн методыг дарж бичнэ
return "Хав хав!"
def татах(self) -> str:
return f"{self.нэр} хүний гарыг татаж байна 🐾"
class Муур(Амьтан):
def дуу_гаргах(self) -> str:
return "Миау~"
def хашгирах(self) -> str:
return f"{self.нэр} гэнэт хашгирлаа 😸"
шарга = Нохой("Шарга", 3)
минни = Муур("Минни", 5)
print(шарга.мэдээлэл()) # Шарга, 3 настай ← Амьтан-аас өвлөсөн
print(шарга.дуу_гаргах()) # Хав хав! ← Нохой-д өөрийн
print(минни.дуу_гаргах()) # Миау~
print(минни.хашгирах()) # Минни гэнэт хашгирлаа 😸
шарга объект мэдээлэл() методыг өөрөө тодорхойлоогүй ч Амьтан-аас өвлөн авсан тул ажилладаг.
super() — parent классыг дуудах
Child class-д __init__ метод нэмэхэд super() ашиглан parent-ийн __init__-г дуудна — кодыг давтахгүйн тулд:
class Ажилтан:
def __init__(self, нэр: str, цалин: float) -> None:
self.нэр = нэр
self.цалин = цалин
def танилцуулах(self) -> str:
return f"{self.нэр} — сарын цалин: {self.цалин:,.0f}₮"
class Менежер(Ажилтан):
def __init__(self, нэр: str, цалин: float, баг_хэмжээ: int) -> None:
super().__init__(нэр, цалин) # Ажилтан-ийн __init__ дуудна
self.баг_хэмжээ = баг_хэмжээ # Менежер-ийн нэмэлт шинж
def танилцуулах(self) -> str:
үндсэн = super().танилцуулах()
return f"{үндсэн}, {self.баг_хэмжээ} хүний багийн ахлагч"
болд = Ажилтан("Болд", 2_500_000)
сарнай = Менежер("Сарнай", 4_000_000, 8)
print(болд.танилцуулах())
# Болд — сарын цалин: 2,500,000₮
print(сарнай.танилцуулах())
# Сарнай — сарын цалин: 4,000,000₮, 8 хүний багийн ахлагч
isinstance() — объектын төрлийг шалгах
print(isinstance(шарга, Нохой)) # True
print(isinstance(шарга, Амьтан)) # True ← өвлөсөн тул мөн Амьтан
print(isinstance(шарга, Муур)) # False
Өвлөлтийн гинжин хэлхээнд child class нь parent классынх гэж тооцогддог — энэ бол OOP-ийн гол давуу тал.
Бодит жишээ: төлбөрийн систем
class Төлбөр:
def __init__(self, дүн: float) -> None:
self.дүн = дүн
def боловсруулах(self) -> str:
return f"{self.дүн:,.0f}₮ төлбөр боловсруулж байна..."
class КартТөлбөр(Төлбөр):
def __init__(self, дүн: float, картын_дугаар: str) -> None:
super().__init__(дүн)
self.картын_дугаар = картын_дугаар
def боловсруулах(self) -> str:
return f"Карт *{self.картын_дугаар[-4:]}: {self.дүн:,.0f}₮ төлөгдлөө ✓"
class QPayТөлбөр(Төлбөр):
def боловсруулах(self) -> str:
return f"QPay: {self.дүн:,.0f}₮ QR кодоор төлөгдлөө ✓"
төлбөрүүд = [
КартТөлбөр(150_000, "1234567890123456"),
QPayТөлбөр(89_900),
КартТөлбөр(320_000, "9876543210001111"),
]
for төлбөр in төлбөрүүд:
print(төлбөр.боловсруулах())
Гаралт:
Карт *3456: 150,000₮ төлөгдлөө ✓
QPay: 89,900₮ QR кодоор төлөгдлөө ✓
Карт *1111: 320,000₮ төлөгдлөө ✓
for давталт Төлбөр объект гэж л мэднэ — КартТөлбөр эсвэл QPayТөлбөр гэдгийг ялгахгүйгээр зөв метод дуудагдана. Үүнийг polymorphism гэдэг бөгөөд OOP-ийн хамгийн хүчирхэг онцлогуудын нэг юм.
Дараагийн хичээлд:
__init__, __str__ зэрэг тусгай методууд (dunder methods)-ийг судлана — классаа print(), len(), нэмэх + зэрэг Python-ийн суурь үйлдлүүдтэй хэрхэн нийцүүлж ажиллуулахыг сурна.