8 min lexim
Trashëgimia
Të ndërtosh mbi atë që ekziston tashmë
Shpesh disa lloje sendesh ndajnë shumicën e sjelljes së tyre dhe ndryshojnë vetëm në një a dy detaje. Një makinë dhe një autobus janë të dyja mjete: të dyja kanë një markë, të dyja mund të nisen, të dyja mund të përshkruajnë veten. Të shkruash dy klasa të plota që përsërisin gjithë atë është shpërdorim, dhe më keq, nëse më vonë rregullon një gabim te pjesa e përbashkët, duhet ta rregullosh te çdo kopje.
Trashëgimia e zgjidh këtë. E shkruan sjelljen e përbashkët një herë te një klasë prind (e quajtur edhe klasë bazë), dhe çdo klasë fëmijë (ose klasë e rrjedhur) e trashëgon atë vetvetiu, duke shtuar ose ndryshuar vetëm atë që e bën të veçantë. Fëmija merr falas gjithçka që ka prindi.
Një klasë prind
Fillo me idenë e përgjithshme, një mjet, dhe vër aty pjesët e përbashkëta.
class Mjet:
def __init__(self, marka, rrota):
self.marka = marka
self.rrota = rrota
def pershkruaj(self):
return f"Një {self.marka} me {self.rrota} rrota"
Çdo mjet mund të përshkruhet, dhe çdo mjet regjistron markën e vet dhe sa rrota ka. Kjo është toka e përbashkët mbi të cilën do të qëndrojnë fëmijët.
Fëmijë që trashëgojnë
Një klasë fëmijë e emërton prindin e vet në kllapa. Menjëherë ka pershkruaj dhe atributet, pa përsëritur asnjë rresht.
class Makine(Mjet):
def hap_bagazhin(self): # diçka që vetëm një makinë e bën
return f"Bagazhi i {self.marka} është i hapur"
class Autobus(Mjet):
def __init__(self, marka, rrota, ulese):
super().__init__(marka, rrota) # lëre prindin të vendosë pjesët e përbashkëta
self.ulese = ulese # pastaj shto atë që është e re
def pershkruaj(self): # zëvendëso versionin e prindit
return f"Një autobus {self.marka} me {self.ulese} ulëse"
Makine shton një metodë të vetën dhe përndryshe mbështetet krejtësisht te Mjet. Autobus ka nevojë për një atribut shtesë, ulese, ndaj shkruan __init__ e vet, por në vend që të kopjojë vendosjen e prindit, thërret super().__init__(...), që ekzekuton __init__ e prindit i pari. Ai rresht i vetëm është mënyra si një fëmijë e ripërdor punën e prindit në vend që ta dyfishojë.
makine = Makine("Fiat", 4)
autobus = Autobus("Setra", 6, 52)
print(makine.pershkruaj()) # Një Fiat me 4 rrota (e trashëguar e pandryshuar)
print(makine.hap_bagazhin()) # Bagazhi i Fiat është i hapur (metoda e vetë makinës)
print(autobus.pershkruaj()) # Një autobus Setra me 52 ulëse (versioni i vetë autobusit)
Mbishkrimi: i njëjti emër, sjellje e re
Vër re se Autobus përcakton pershkruaj e vet. Kur një fëmijë shkruan një metodë me të njëjtin emër si një te prindi, versioni i fëmijës fiton për objektet e atij fëmije. Kjo quhet mbishkrim, dhe është mënyra si një fëmijë mban shumicën e prindit por ndryshon pjesët që duhet të ndryshojnë. makine.pershkruaj() përdor versionin e trashëguar; autobus.pershkruaj() përdor të vetin.
Këshillë
Përdor trashëgiminë kur mund të thuash me ndershmëri "një fëmijë është një lloj prindi": një makinë është një lloj mjeti, një llogari kursimi është një lloj llogarie. Nëse fjalia tingëllon gabim, për shembull "një rrotë është një lloj makine", atëherë sendi është një pjesë, jo një fëmijë, dhe trashëgimia është vegla e gabuar.
Trashëgimia e mban kodin e përbashkët në një vend dhe e lë çdo fëmijë të mbetet i vogël, duke mbajtur vetëm atë që është vërtet e vetja. Rregullo ose përmirëso prindin, dhe çdo fëmijë përmirësohet bashkë me të. Në mësimin tjetër do të shohësh pse ndarja e emrave të metodave nga fëmijët nuk është thjesht e rregullt, por vërtet e fuqishme.
Do ta shohësh të shpjeguar? Ja leksioni i regjistruar i Code for Albania për këtë temë.
Provoje tani
Shkruaj një klasë prind Kafshe me emri dhe një metodë fol() që kthen një tingull të përgjithshëm. Bëj një fëmijë Qen(Kafshe) që mbishkruan fol() për të lehur, dhe një fëmijë Mace(Kafshe) që shton një atribut brenda në __init__ e vet duke përdorur super().__init__(...). Ndërto nga një prej secilit dhe thirr fol() te të dy.
Provo veten
- Çfarë merr një klasë fëmijë nga prindi i saj pa shkruar asnjë rresht kod, dhe pse e zvogëlon kjo si mundimin ashtu edhe gabimet?
Autobusthërretsuper().__init__(marka, rrota)brenda__init__të vet. Çfarë do të shkonte keq, ose do të përsëritej, nëse nuk do të përdortesuper()dhe në vend të kësaj do të vendoste çdo atribut me dorë?- Si
Mjetashtu edheAutobuspërcaktojnë një metodëpershkruaj. Kur thërretautobus.pershkruaj(), cila ekzekutohet, dhe si quhet ajo sjellje?
Nga vjen ky mësim
Ndërtuar mbi
- Data Structures and Algorithms
Kurset e alphaPlan ndërtohen mbi programe të zhvilluara në klasë, e nuk shpiken për web-in. Kur një pohim mbështetet mbi një standard të jashtëm ose mbi një rast të raportuar, ai emërtohet më sipër që ta kontrollosh vetë e të mos na besosh në fjalë.
Ky kurs u zhvillua nga alphaPlan Center mbi bazën e programeve të realizuara në partneritet me rrjetin American Corners.
Gjete diçka të paqartë, të vjetruar ose që mund të përmirësohet? Sugjero një përmirësim