Kalo te përmbajtja

8 min lexim

American Corners

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__init__ e vet duke përdorur super().__init__(...). Ndërto nga një prej secilit dhe thirr fol() te të dy.

Provo veten

  1. Ç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?
  2. Autobus thërret super().__init__(marka, rrota) brenda __init__ të vet. Çfarë do të shkonte keq, ose do të përsëritej, nëse nuk do të përdorte super() dhe në vend të kësaj do të vendoste çdo atribut me dorë?
  3. Si Mjet ashtu edhe Autobus përcaktojnë një metodë pershkruaj. Kur thërret autobus.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