Kalo te përmbajtja

8 min lexim

American Corners

Kapsulimi dhe abstraksioni

Të fshehësh instalimet

Kur përdor një telefon, shtyp ca butona; nuk i prek qarqet brenda. Ajo ndarje, një sipërfaqe e thjeshtë mbi një brendësi të mbrojtur, është ajo që këto dy ide u japin objekteve të tua. Kapsulimi i mban të dhënat e një objekti të futura pas metodave të tij, që asgjë nga jashtë të mos i prishë në heshtje. Abstraksioni shkon më tej dhe të lejon të përshkruash çfarë duhet të dijë të bëjë një lloj objekti, duke ia lënë të si-në çdo objekti të veçantë. Të dyja i bëjnë programet më të lehta për t'u besuar dhe më të lehta për t'u ndryshuar.

Publik, i mbrojtur dhe privat

Python e shënon se sa lirisht duhet prekur një atribut duke përdorur nënvija te emri i tij. Sipas konventës ka tri nivele.

  • Një emër i thjeshtë si balanca është publik: kushdo mund ta lexojë ose ndryshojë.
  • Një nënvijë e vetme në krye, _balanca, e shënon si të mbrojtur: një shenjë e sjellshme që do të thotë "e brendshme, mos e prek nga jashtë". Python nuk të ndalon, por je paralajmëruar.
  • Dy nënvija në krye, __balanca, e bën privat: Python e ndryshon aktivisht emrin, që kodi jashtë klasës të mos e arrijë dot nga rruga e dukshme.
class KarteDhurate:
    def __init__(self, shuma):
        self.__balanca = shuma         # private: e mbajtur brenda klasës

    def merr_balancen(self):
        return self.__balanca

    def shpenzo(self, shuma):
        if 0 < shuma <= self.__balanca:
            self.__balanca = self.__balanca - shuma
        else:
            print("Shumë e pavlefshme")

karte = KarteDhurate(50)
karte.shpenzo(20)
print(karte.merr_balancen())    # 30
print(karte.__balanca)          # AttributeError: s'ka atribut të tillë

Rreshti i fundit dështon me qëllim. Meqë __balanca është private, bota e jashtme s'e prek dot drejtpërdrejt dhe s'e vë dot kartën në një vlerë të pakuptimtë. Rruga e vetme brenda është nëpërmjet shpenzo, që e kontrollon shumën fillimisht.

Getter-at, setter-at dhe pse rojtojnë

Të dhënat private arrihen nëpërmjet metodave getter dhe setter, pikërisht siç i takove më parë. Arsyeja pse i detyron të gjitha të kalojnë nëpër to është kontrolli. shpenzo është vërtet një setter i rojtuar: refuzon një shumë negative ose më të madhe se balanca, që karta të mos bjerë kurrë në një gjendje të pamundur. Po të ishte balanca publike, çdo rresht i humbur kudo mund ta vinte në një numër negativ dhe askush s'do ta vinte re deri shumë vonë.

Këshillë

Kapsulimi nuk ka të bëjë me fshehtësinë për hir të vetes. Ka të bëjë me t'i dhënë çdo objekti një derë të vetme të rojtuar në vend të shumë dritareve të hapura, që kur diçka vërtet shkon keq, të ketë vetëm pak vende për të parë. Sa më pak mënyra të ketë për ta ndryshuar një vlerë, aq më lehtë është ta mbash atë vlerë të saktë.

Mëso më shumë

Abstraksioni është gjysma tjetër. Ndonjëherë do të premtosh se çdo objekt i një familjeje të caktuar do të japë një metodë, pa e shkruar atë metodë te prindi, sepse çdo fëmijë e bën ndryshe. Python ofron klasa bazë abstrakte nëpërmjet modulit abc pikërisht për këtë.

from abc import ABC, abstractmethod

class MenyrePagese(ABC):
    @abstractmethod
    def paguaj(self, shuma):
        pass                       # pa trup: çdo fëmijë duhet të japë një të tillë


class PageseMeKarte(MenyrePagese):
    def paguaj(self, shuma):
        return f"U ngarkuan {shuma} te karta"


class PageseMeKesh(MenyrePagese):
    def paguaj(self, shuma):
        return f"U morën {shuma} në kesh"

MenyrePagese trashëgon nga ABC dhe e shënon paguaj me @abstractmethod, duke i dhënë asnjë trup të vërtetë. Kjo bën dy gjëra. Nuk krijon dot fare një MenyrePagese() të zhveshur, sepse është e paplotë. Dhe çdo fëmijë detyrohet të japë paguaj të vetin, ose Python refuzon ta ndërtojë. Klasa bazë e shpall kontratën, "një mënyrë pagese duhet të jetë e pagueshme", dhe abstraksioni ua lë detajet çdo lloji. Rreshti me @ këtu është një dekorator; do ta takosh atë sintaksë si duhet më vonë.

for menyra in (PageseMeKarte(), PageseMeKesh()):
    print(menyra.paguaj(30))

# U ngarkuan 30 te karta
# U morën 30 në kesh

Kapsulimi e fsheh brendësinë që të dhënat të mbeten të sigurta; abstraksioni e ngul jashtësinë që çdo pjesëtar i familjes ta nderojë të njëjtën kontratë. Bashkë të lejojnë të ndërtosh programe të mëdha nga pjesë që mund t'u besosh pa lexuar brendësinë e tyre.

Do ta shohësh të shpjeguar? Ja leksioni i regjistruar i Code for Albania për këtë temë.

Provoje tani

Shkruaj një klasë KarteDhurate si ajo sipër, duke e ruajtur balancën në një __balanca private. Jepi një metodë shpenzo(shuma) që zbret vetëm kur 0 < shuma <= self.__balanca. Bëj një kartë me vlerë 50, shpenzo 20, shtyp balancën nëpërmjet një getter-i, pastaj provo karte.__balanca drejtpërdrejt dhe shihe të dështojë. Ai dështim është kapsulimi që punon.

Provo veten

  1. Cili është ndryshimi praktik mes një nënvije të vetme _emri dhe dy nënvijave __emri, dhe cilin e zbaton vërtet Python?
  2. Metoda shpenzo refuzon një shumë negative ose të tepërt. Shpjego si e bërja e __balanca private, në vend të publike, është ajo që e bën atë rojtar kuptimplotë.
  3. MenyrePagese është një klasë bazë abstrakte me një metodë abstrakte paguaj. Cilat dy gjëra i pengon shënimi i saj në atë mënyrë, dhe pse është kjo e dobishme kur njerëz të tjerë shkruajnë lloje të reja pagese?

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