Çfarë është OOP me shembuj. Për fillestarë

(OOP) organizon të dhënat dhe algoritmet e përpunuara nga programi. Në këtë rast, programuesi krijon forma të dhënash dhe algoritme që korrespondojnë me karakteristikat kryesore të problemit që zgjidhet. Modelet e të dhënave dhe algoritmet që i përpunojnë ato quhen klasat, A objektet- këta janë përfaqësuesit e tyre specifik të përdorur në program.

Nga objektet e përgjithshme krijohen të tjera, më të specializuara. Mekanizmi për krijimin e nënobjekteve të tilla quhet trashëgimisë. Si rezultat, këto programe janë modeli i objektit- një pemë objektesh, duke filluar me objektin më abstrakt dhe të përgjithshëm.

OOP kombinon parimet më të mira të programimit të strukturuar me koncepte të reja të fuqishme, ato themelore quhen enkapsulim, polimorfizëm dhe trashëgimi.

Një shembull i gjuhëve të orientuara nga objekti janë: Object Pascal , C++, Java.

OOP ju lejon të organizoni në mënyrë optimale programet duke thyer një problem në pjesët përbërëse të tij dhe duke punuar me secilën veç e veç.

Programim i orientuar nga objektiështë një zhvillim i teknologjisë së programimit të strukturuar, por ka veçoritë e veta karakteristike. Njësia bazë në programimin e orientuar nga objekti është një objekt, i cili përmban dhe përmbledh si të dhënat që e përshkruajnë atë (vetitë) ashtu edhe mjetet për përpunimin e këtyre të dhënave (metodat). Sistemet OOP zakonisht përdorin një ndërfaqe grafike për të vizualizuar procesin e programimit. Bëhet e mundur krijimi i objekteve, vendosja e vetive dhe sjelljes së tyre duke përdorur miun.

Nje objektështë një kombinim i të dhënave dhe kodit. Me fjalë të tjera, një objekt i quajtur gjithashtu përfaqësues(i një klase) është një pjesë e të dhënave, vlera e së cilës përcakton gjendjen e saj aktuale dhe një grup nënprogramesh të quajtura metodat duke vepruar me këto të dhëna dhe duke përcaktuar sjellje objekt, d.m.th. reagimi i tij ndaj ndikimeve të jashtme.

Objekti përbëhet nga tre pjesët e mëposhtme:

Emri i objektit;

Gjendja (variablat e gjendjes);

Metodat (operacionet).

Çdo objekt është një përfaqësues (instancë) e një të caktuar klasës. Gjatë ekzekutimit të programit, objektet ndërveprojnë me njëri-tjetrin duke thirrur metoda, të cilat janë nënprograme specifike për një klasë të caktuar.

Klasa(klasa) është një grup të dhënash dhe metodash (funksionesh) për të punuar me këto të dhëna. Ky është një shabllon. Objektet me të njëjtat veti, domethënë me të njëjtat grupe variablash dhe metodash të gjendjes, formojnë një klasë. Një objekt është një zbatim konkret, një shembull i një klase. Në programim, marrëdhënia midis një objekti dhe një klase mund të krahasohet me përshkrimin e një ndryshoreje, ku vetë ndryshorja (objekt) është një shembull i një lloji të të dhënave (klasë).


Programimi i orientuar nga objekti zbret në krijimin e një numri të caktuar klasash, përshkrimin e marrëdhënieve midis këtyre klasave dhe vetive të tyre dhe zbatimin e mëtejshëm të klasave që rezultojnë.

Qasja teorike. Klasaështë një nga opsionet për përshkrimin e një entiteti, i cili në teorinë e programimit quhet tip abstrakt i të dhënave. Një klasë përcakton strukturën e brendshme të fshehur të një vlere, si dhe një grup operacionesh që mund të zbatohen në atë vlerë.

Qasje praktike. Në gjuhët moderne të programimit të orientuara nga objekti (php, Java, C++, Oberon, Python, Ruby, Smalltalk, Object Pascal), krijimi i një klase zbret në shkrimin e një strukture që përmban një sërë fushash dhe metodash. Në praktikë, një klasë mund të kuptohet si një lloj shablloni sipas të cilit krijohen objekte - shembuj të një klase të caktuar. Instancat e së njëjtës klasë krijohen duke përdorur të njëjtin shabllon, dhe për këtë arsye kanë të njëjtin grup fushash dhe metodash.

Marrëdhëniet ndërmjet klasave:

Trashëgimia (Gjeneralizimi) - objektet e një klase fëmijë trashëgojnë të gjitha vetitë e klasës mëmë.

Shoqata - objektet e klasave ndërveprojnë me njëri-tjetrin.

Agregimi - objektet e një klase përfshihen në objektet e një tjetri.

Përbërja - objektet e një klase përfshihen në objektet e një tjetri dhe varen nga njëri-tjetri për sa i përket jetëgjatësisë.

Klasa-Metaclass është një marrëdhënie në të cilën klasat e tjera janë shembuj të një klase.

Llojet e klasave:

Klasa bazë (prind);

Klasa e prejardhur (pasardhës, pasardhës);

Klasa abstrakte;

Klasa virtuale;

Ndërfaqja.

Një klasë është një lloj i të dhënave strukturore që përfshin një përshkrim të fushave të të dhënave, si dhe procedurat dhe funksionet që funksionojnë në këto fusha të dhënash. Në lidhje me klasat quhen procedura dhe funksione të tilla metodat.

Metodat- procedurat dhe funksionet e inkapsuluara në një klasë, domethënë mënyrat e punës me të dhënat.

Klasat dhe programimi i orientuar nga objekti bazohen në tre parime: - kapsulimi, trashëgimisë Dhe polimorfizëm.

Kapsulimi(fshehja) është një veti e një gjuhe programimi që ju lejon të kombinoni të dhënat dhe kodin në një objekt dhe të fshehni zbatimin e objektit nga përdoruesi. Në këtë rast, përdoruesi pajiset vetëm me specifikimin (ndërfaqen) e objektit. Përdoruesi mund të ndërveprojë me objektin vetëm përmes kësaj ndërfaqe.

Më shpesh, kapsulimi realizohet përmes fshehjes së informacionit, domethënë maskimit të të gjitha detajeve të brendshme që nuk ndikojnë në sjelljen e jashtme. Zakonisht si struktura e brendshme e një objekti ashtu edhe zbatimi i metodave të tij janë të fshehura.

Qëllimet e kapsulimit:

§ lokalizimi ekstrem i ndryshimeve nëse ndryshime të tilla janë të nevojshme,

§ parashikueshmëria e ndryshimeve (çfarë ndryshimesh duhet të bëhen në kod për një ndryshim të caktuar në funksionalitet) dhe parashikueshmëria e pasojave të ndryshimeve.

Kapsulimi- ky është procesi i ndarjes nga njëri-tjetri i elementeve të një objekti që përcaktojnë strukturën dhe sjelljen e tij. Shpesh kapsulimi mund të arrihet me masa të thjeshta organizative: të dish se "kjo nuk është diçka që nuk mund ta bësh" ndonjëherë është mjeti më efektiv i kapsulimit!

Kapsulimi- Kombinimi i të dhënave me procedurat dhe funksionet që manipulojnë fushat e këtyre rekordeve formon një lloj të ri të dhënash - një objekt.

Kapsulimi- izolimi i komponentëve të klasës (fushat, metodat dhe vetitë) nga pjesët e tjera të programit.

Thelbi i kapsulimit: Variablat e gjendjes së objektit janë të fshehura nga bota e jashtme. Ndryshimi i gjendjes së një objekti (ndryshoret e tij) është i mundur VETËM duke përdorur metodat (operacionet) e tij. Pse është kjo kaq e rëndësishme? Ky parim ju lejon të mbroni variablat e gjendjes së objektit nga keqpërdorimi.

Përdorimi i kësaj metode çon në një ulje të efikasitetit të aksesit në elementët e objektit. Kjo është për shkak të nevojës për të thirrur metoda për të ndryshuar elementët e brendshëm (variablat) e objektit. Megjithatë, në nivelin aktual të zhvillimit të teknologjisë kompjuterike, këto humbje në efikasitet nuk luajnë një rol të rëndësishëm.

Trashëgimia- një nga katër mekanizmat më të rëndësishëm të programimit të orientuar nga objekti (së bashku me kapsulimin, polimorfizmin dhe abstraksionin), i cili ju lejon të përshkruani një klasë të re bazuar në një (prind) tashmë ekzistues, ndërsa vetitë dhe funksionaliteti i klasës mëmë janë huazuar nga klasa e re.

Trashëgimia- ky është procesi me të cilin një objekt mund të trashëgojë vetitë e një objekti tjetër dhe t'u shtojë atyre veçori karakteristike vetëm për të. Kuptimi dhe universaliteti i trashëgimisë qëndron në faktin se nuk keni nevojë të përshkruani një objekt të ri çdo herë (nga e para), por mund të specifikoni prindin (klasën bazë) dhe të përshkruani tiparet dalluese të klasës së re. Si rezultat, objekti i ri do të ketë të gjitha vetitë e klasës mëmë plus veçoritë e veta dalluese.

Trashëgimia- paraqet mundësinë e ndërtimit të një hierarkie të objekteve duke përdorur trashëgiminë e karakteristikave të tyre.

Trashëgimia. Trashëgimia është një veti e një objekti që e lejon atë të përdorë fushat dhe metodat e objektit prind, pa i përshkruar ato në strukturën e tij.

Trashëgimia- aftësia për të krijuar klasa të reja bazuar në ato ekzistuese me aftësinë për të përdorur komponentët e tyre. Një objekt që i përket një klase pasardhëse mund të përdorë fushat, vetitë dhe metodat e klasës mëmë dhe komponentët e rinj të klasës së saj.

Nëse një metodë e re me të njëjtin emër si një metodë e klasës prind përshkruhet në një klasë pasardhëse, atëherë thuhet se metoda e prindit është "të anashkaluar" në pasardhësin. Me fjalë të tjera, një klasë pasardhëse zbaton specifikimin e një klase tashmë ekzistuese (klasa bazë). Kjo ju lejon të trajtoni objektet e një klase pasardhëse në të njëjtën mënyrë si objektet e një klase bazë. Kur krijohet një hierarki klasash, disa veti të objekteve, duke ruajtur emrat, ndryshojnë në thelb.

Për të zbatuar hierarki të tilla, gjuha e programimit ofron polimorfizëm. Fjala polimorfizëm është me origjinë greke dhe përkthehet si "ka shumë forma".

Polimorfizmi. Dhënia e një veprimi një emër të vetëm, i cili më pas ndahet poshtë dhe lart në hierarkinë e objekteve, me secilin objekt në hierarki që e kryen atë veprim në një mënyrë që është e përshtatshme për të.

Polimorfizmiështë një veti që lejon të përdoret i njëjti emër për të zgjidhur disa probleme teknikisht të ndryshme.

Në terma OOP, mund të themi se të gjitha llojet e butonave të ndërfaqes kanë aftësinë të shfaqen në ekran. Megjithatë, metoda (procedura) është e ndryshme për çdo lloj butoni. Një buton i thjeshtë vizatohet në ekran duke përdorur procedurën "shfaqja e një imazhi të një butoni të thjeshtë", një buton ndërprerës vizatohet në ekran duke përdorur procedurën "shfaqja e një imazhi të një butoni ndërprerës" etj.

Kështu, ekziston një veprim i vetëm për të gjithë listën e butonave të ndërfaqes (duke shfaqur imazhin e butonit në ekran), i cili zbatohet në një mënyrë specifike për secilin buton. Ky është një manifestim i polimorfizmit.

Polimorfizmi- aftësia e klasave për të zgjidhur probleme të ngjashme në mënyra të ndryshme. Kur një metodë prindërore anashkalohet, një algoritëm i ri për zgjidhjen e problemit zbatohet tek fëmija. Rezulton se në objektin prind dhe objektin fëmijë ka dy metoda me të njëjtin emër, të cilat kanë një bazë algoritmike të ndryshme.

Polimorfizmi- kjo është një metodë për të vepruar me një grup objektesh të të njëjtit paraardhës në një hap, pa detajuar operacionet me secilin objekt specifik. Ai është gjithashtu baza për zgjerimin e programeve të orientuara nga objekti, sepse ofron një mënyrë për programet e vjetra për të pranuar lloje të reja të dhënash që nuk janë përcaktuar kur programi është shkruar.

Në një kuptim të përgjithshëm, koncepti i polimorfizmit është ideja e "një ndërfaqe, shumë metoda". Kjo do të thotë që ju mund të krijoni një ndërfaqe të përbashkët për një grup veprimesh të lidhura.

Avantazhi Polimorfizmi është se ai ndihmon në reduktimin e kompleksitetit të programit duke lejuar që një ndërfaqe e vetme të përdoret për një klasë të vetme veprimesh. Zgjedhja e një veprimi specifik, në varësi të situatës, varet nga përpiluesi.

Në OOP, qëllimi i polimorfizmit është të përdorë një emër të vetëm për të përcaktuar veprimet e zakonshme për një klasë. Në praktikë, kjo nënkupton aftësinë e objekteve për të zgjedhur një procedurë (metodë) të brendshme bazuar në llojin e të dhënave të marra në mesazh.

Mekanizmi i funksionimit të OOP në raste të tilla mund të përshkruhet diçka e tillë: kur thirrni një ose një metodë tjetër të klasës, së pari kërkohet metoda e vetë klasës. Nëse gjendet një metodë, ajo ekzekutohet dhe kërkimi për këtë metodë përfundon. Nëse metoda nuk gjendet, atëherë i drejtohemi klasës prind dhe kërkojmë metodën e thirrur në të. Nëse gjendet, ne vazhdojmë sikur të kemi gjetur një metodë në vetë klasën. Dhe nëse jo, ne vazhdojmë të kërkojmë më tej pemën hierarkike. Deri në rrënjën (klasa e lartë) e hierarkisë.

Parimet dhe fazat themelore të orientimit nga objekti

programimit

Në teorinë e programimit, OOP përkufizohet si një teknologji për krijimin e softuerit kompleks, i cili bazohet në paraqitjen e një programi si një koleksion objektesh, secila prej të cilave është një shembull i një lloji (klase) të caktuar, dhe klasat formojnë një hierarki me

trashëgimia e pronave.

Ndërveprimi i objekteve softuerike në një sistem të tillë kryhet duke kaluar mesazhe.

Shënim. Ky përfaqësim i programit u përdor për herë të parë në gjuhën e simulimit për sistemet komplekse Simula, e cila u shfaq në vitet '60.

Mënyra e përfaqësimit të një programi, e cila është e natyrshme për gjuhët e modelimit, u zhvillua në një gjuhë tjetër të specializuar modelimi - gjuhën Smalltalk (vitet 70), dhe më pas u zhvillua

Faqja 2 nga 51

Parimet themelore të OOP

përdoret në versionet e reja të gjuhëve universale të programimit si Pascal, C++,

Avantazhi kryesor i OOP- reduktimi i numrit të thirrjeve ndërmodule dhe reduktimi i sasisë së informacionit të transferuar ndërmjet moduleve,

krahasuar me programimin modular. Kjo arrihet përmes lokalizimit më të plotë të të dhënave dhe integrimit me rutinat e përpunimit,

e cila lejon zhvillimin praktikisht të pavarur të pjesëve individuale

(objektet) e programit.

Përveç kësaj, qasja objekt ofron mjete të reja të zhvillimit teknologjik, si p.sh trashëgimia, polimorfizmi, përbërja, përmbajtja,

duke ju lejuar të ndërtoni objekte komplekse nga më të thjeshtat. Si rezultat, shkalla e ripërdorimit të kodit rritet ndjeshëm,

Bëhet e mundur krijimi i bibliotekave të objekteve për aplikacione të ndryshme, dhe zhvilluesve u jepen mundësi shtesë për të krijuar sisteme me kompleksitet të shtuar.

Disavantazhi kryesor i OOP është një rënie e lehtë e performancës për shkak të një organizimi më kompleks të sistemit të softuerit.

OOP bazohet në parimet e mëposhtme: abstraksion,

kufizimi i aksesit, modulariteti, hierarkia, shtypja, paralelizmi,

qëndrueshmëri.

Le të shohim se cili është secili parim.

A b p s t r a g e- procesi i identifikimit të abstraksioneve në fushën lëndore të një detyre. Abstraksioni është një grup karakteristikash thelbësore të një objekti që e dallojnë atë nga të gjitha llojet e tjera të objekteve dhe,

pra, ato përcaktojnë qartë veçoritë e një objekti të caktuar nga pikëpamja e shqyrtimit dhe analizës së mëtejshme. Në përputhje me përkufizimin, abstraksioni i përdorur i një objekti real varet ndjeshëm nga problemi që zgjidhet: në një rast do të na interesojë forma e objektit, në një tjetër pesha, në

e treta - materialet nga të cilat është bërë, së katërti - ligji i lëvizjes

Faqja 3 nga 51

Parimet themelore të OOP

subjekti etj. Niveli modern i abstraksionit përfshin unifikimin e të gjitha vetive të abstraksionit (të dyja ato që kanë të bëjnë me gjendjen e objektit të analizuar,

dhe përcaktimi i sjelljes së tij) në një njësi të vetme programore një të caktuar

lloji (klasa) abstrakt.

Kufizimi i aksesit- fshehja e elementeve individuale të zbatimit të abstraksionit që nuk prekin karakteristikat thelbësore të tij në tërësi.

Nevoja për të kufizuar aksesin kërkon një dallim midis dy pjesëve në përshkrimin e abstraksionit:

ndërfaqe - një grup elementesh të zbatimit të abstraksionit të arritshëm nga jashtë (karakteristikat kryesore të gjendjes dhe sjelljes);

zbatim - një grup elementesh të zbatimit të një abstraksioni që janë të paarritshëm nga jashtë (organizimi i brendshëm i abstraksionit dhe mekanizmat për zbatimin e sjelljes së tij).

Kufizimi i aksesit në OOP i lejon zhvilluesit të:

të kryejë ndërtimin e sistemit në faza, pa u hutuar nga veçoritë e zbatimit të abstraksioneve të përdorura;

është e lehtë të modifikohet zbatimi i objekteve individuale, të cilat në një sistem të organizuar siç duhet nuk do të kërkojnë ndryshime në objekte të tjera.

Kombinimi i kombinimit të të gjitha vetive të një objekti (përbërësit e gjendjes dhe sjelljes së tij) në një abstraksion të vetëm dhe kufizimi i aksesit në zbatimin e këtyre vetive quhet enkapsulim.

MODULARITETI- parimi i zhvillimit të një sistemi softuerësh,

duke sugjeruar zbatimin e tij në formën e pjesëve (moduleve) të veçanta. Kur zbërthehet një sistem në module, është e dëshirueshme të kombinohen pjesët e lidhura logjikisht, duke siguruar, nëse është e mundur, një reduktim të numrit të lidhjeve të jashtme midis moduleve. Parimi është i trashëguar nga

Faqja 4 nga 51

Parimet themelore të OOP

programimi modular, ndjekja e tij thjeshton dizajnin dhe

korrigjimi i programit.

Hierarkia është një sistem i renditur ose i renditur i abstraksioneve.

Parimi i hierarkisë përfshin përdorimin e hierarkive në zhvillimin e sistemeve softuerike.

OOP përdor dy lloje hierarkie.

Hierarkia "e tërë/pjesë"- tregon se disa abstraksione janë aktivizuar

në abstraksionin në fjalë si pjesë të tij, për shembull, një llambë përbëhet nga një bazë, një filament inkandeshent dhe një llambë. Ky version i hierarkisë përdoret në procesin e ndarjes së sistemit në faza të ndryshme të projektimit (në nivelin logjik - kur zbërthehet zona e subjektit në objekte, në nivelin fizik - kur zbërthehet sistemi në module dhe kur ndahen proceset individuale në një sistem me shumë procese).

Hierarkia "e përgjithshme/private"- tregon se disa abstraksione janë një rast i veçantë i një abstraksioni tjetër, për shembull, "tavolina e ngrënies -

një lloj tavoline specifike" dhe "tavolinat janë një lloj specifik mobiljesh". Përdoren për

zhvillimi i strukturës së klasës, kur klasat komplekse ndërtohen mbi bazën e atyre më të thjeshta duke u shtuar karakteristika të reja dhe, mundësisht, duke sqaruar ato ekzistuese.

Një nga mekanizmat më të rëndësishëm të OOP është trashëgimia e pronave në hierarkinë publike/private. Trashëgimia është një marrëdhënie midis abstraksioneve kur njëri prej tyre përdor një pjesë strukturore ose funksionale të një tjetri ose disa abstraksione të tjera (përkatësisht të thjeshta dhe të shumëfishta.

trashëgimia).

TIPZATION - një kufizim i vendosur në vetitë e objekteve dhe

duke parandaluar këmbyeshmërinë e abstraksioneve të llojeve të ndryshme (ose duke reduktuar në masë të madhe mundësinë e një zëvendësimi të tillë). Në gjuhë të shtypura fort, për çdo objekt programi (ndryshore, nënprogram, parametër, etj.)

deklaron një lloj që përcakton një grup operacionesh në

Faqja 5 nga 51

Parimet themelore të OOP

objekt softuerik përkatës. Gjuhët e programimit të bazuara në Pascal të diskutuara më poshtë përdorin strikte, dhe ato të bazuara në C -

shkalla mesatare e tipizimit.

Përdorimi i parimit të shtypjes siguron:

zbulimi i hershëm i gabimeve që lidhen me operacionet e pavlefshme në objektet e programit (gabimet zbulohen në fazën e përpilimit të programit kur kontrolloni pranueshmërinë e kryerjes së një operacioni të caktuar në një objekt programi);

thjeshtimi i dokumentacionit;

aftësia për të gjeneruar kode më efikase.

Një lloj mund të shoqërohet me një objekt softuerësh në mënyrë statike (lloji i objektit përcaktohet në kohën e përpilimit - lidhja e hershme) dhe në mënyrë dinamike (lloji i objektit përcaktohet vetëm gjatë ekzekutimit të programit - lidhja e vonë). Zbatimi i lidhjes së vonë në një gjuhë programimi ju lejon të krijoni variabla - tregues për objektet që i përkasin klasave të ndryshme (objekte polimorfike), gjë që zgjeron ndjeshëm aftësitë e gjuhës.

P a r l l e l i s m- vetia e disa abstraksioneve të jenë në gjendje aktive në të njëjtën kohë, d.m.th. kryejnë disa operacione.

Ekzistojnë një numër detyrash, zgjidhja e të cilave kërkon ekzekutimin e njëkohshëm të sekuencave të caktuara të veprimeve. Për detyra të tilla

për shembull, detyrat e kontrollit automatik të disa proceseve.

Paralelizmi real arrihet vetëm kur zbatohen detyra të këtij lloji në sistemet multiprocesorike, kur është e mundur të ekzekutohet çdo proces në një procesor të veçantë. Sistemet me një procesor simulojnë paralelizmin duke e ndarë kohën e procesorit midis detyrave të menaxhimit të proceseve të ndryshme. Në varësi të llojit të sistemit operativ të përdorur (i vetëm ose me shumë program)

Faqja 6 nga 51

Parimet themelore të OOP

ndarja e kohës mund të bëhet ose nga sistemi që po zhvillohet (si në

MS DOS), ose OS i përdorur (si në sistemet Windows).

Stabiliteti- vetia e një abstraksioni të ekzistojë në kohë, pavarësisht nga procesi që gjeneroi një objekt të caktuar softuer, dhe/ose në hapësirë, duke lëvizur nga hapësira e adresave në të cilën është krijuar.

Atje jane:

∙ objekte të përkohshme që ruajnë rezultate të ndërmjetme të veprimeve të caktuara, siç janë llogaritjet;

∙ objekte lokale që ekzistojnë brenda nënprogrameve, jetëgjatësia e të cilave llogaritet nga thirrja e nënprogramit deri në përfundimin e saj;

∙ objekte globale që ekzistojnë ndërsa programi është i ngarkuar në memorie;

∙ objekte të ruajtura, të dhënat e të cilave ruhen në skedarët e memories së jashtme ndërmjet sesioneve të programit.

Të gjitha parimet e mësipërme zbatohen në një shkallë ose në një tjetër në versione të ndryshme të gjuhëve të orientuara nga objekti.

Gjuhët e programimit të orientuara nga objekti. Gjuha ka rëndësi i orientuar nga objekti,nëse zbaton katër të parat nga shtatë parimet e diskutuara.

Një vend të veçantë zënë modelet e objekteve Delphi dhe C++Builder. Këto modele përgjithësojnë përvojën e OOP për MS DOS dhe përfshijnë disa veçori të reja,

duke siguruar krijimin efikas të sistemeve më komplekse. Bazuar në këto modele, janë krijuar mjedise vizuale për zhvillimin e aplikacioneve Windows.

Kompleksiteti i programimit nën Windows është tejkaluar ndjeshëm

reduktohet duke krijuar biblioteka të veçanta objektesh që “fshehnin” shumë elementë të teknikave programuese.

Faqe 7 nga 51

Parimet themelore të OOP

Fazat e zhvillimit të sistemeve softuerike duke përdorur OOP.

Procesi i zhvillimit të softuerit duke përdorur OOP përfshin katër faza: analizë, dizajn, evolucion, modifikim.

Le të shohim këto faza.

Analiza . Qëllimi i analizës është përshkrimi më i plotë i problemit. Në këtë fazë, kryhet një analizë e fushës së problemit, kryhet një dekompozim i objektit të sistemit që po zhvillohet dhe përcaktohen tiparet më të rëndësishme të sjelljes së objekteve (përshkrimi i abstraksioneve). Bazuar në rezultatet e analizës, zhvillohet një bllok diagram i produktit softuer, i cili tregon objektet dhe mesazhet kryesore të transmetuara midis tyre, si dhe përshkruan abstraksionet.

Dizajn. Atje jane:

dizajn logjik, në të cilat vendimet e marra janë praktikisht të pavarura nga kushtet e funksionimit (sistemi operativ dhe pajisjet e përdorura);

dizajni fizik, në të cilat duhet të merren parasysh këta faktorë.

Dizajn logjikështë të zhvilloni një strukturë klase:

Përcaktohen fushat për ruajtjen e komponentëve të gjendjes së objekteve dhe algoritmet e metodave që zbatojnë aspekte të sjelljes së objekteve. Në këtë rast, përdoren teknikat e zhvillimit të klasës të diskutuara më sipër (trashëgimi,

përbërja, përmbajtja, polimorfizmi etj.). Rezultati është një hierarki ose diagram klasë që tregon marrëdhëniet ndërmjet klasave dhe një përshkrim të klasave.

Dizajni fizik përfshin kombinimin e përshkrimeve të klasave në module, zgjedhjen e skemës së lidhjes së tyre (paraqitje statike ose dinamike), përcaktimin e mënyrave për të ndërvepruar me pajisjet, me

sistemi operativ dhe/ose softuer tjetër (për shembull,

bazat e të dhënave, programet e rrjetit), duke siguruar sinkronizimin e proceseve për sistemet e përpunimit paralel, etj.

Faqja 8 nga 51

Parimet themelore të OOP

Evolucioni i sistemeve. Ky është një proces i zbatimit hap pas hapi dhe

lidhja e klasave me projektin. Procesi fillon me krijimin e një programi ose projekti bazë për një produkt të ardhshëm softuer. Pastaj klasat zbatohen dhe lidhen në mënyrë që të krijohet një përafërt, por, nëse është e mundur,

një prototip funksional i sistemit të ardhshëm. Është testuar dhe debuguar.

Për shembull, një prototip i tillë mund të jetë një sistem që përfshin zbatimin e ndërfaqes kryesore të një produkti softuer (mesazhet nuk transmetohen në një pjesë të sistemit që nuk është ende i disponueshëm). Si rezultat, ne marrim një prototip pune të produktit, i cili, për shembull, mund t'i tregohet klientit për të sqaruar kërkesat. Pastaj grupi tjetër i klasave është i lidhur me sistemin, për shembull, i lidhur me zbatimin e një artikulli të caktuar të menysë.

Versioni që rezulton gjithashtu testohet dhe korrigjohet, e kështu me radhë, derisa të realizohen të gjitha aftësitë e sistemit.

Përdorimi i një zbatimi me faza thjeshton shumë testimin dhe korrigjimin e një produkti softuerësh.

Modifikimi. Është procesi i shtimit të funksionalitetit të ri ose ndryshimit të vetive ekzistuese të sistemit. Zakonisht,

ndryshimet ndikojnë në zbatimin e klasës, duke lënë ndërfaqen e saj të pandryshuar, gjë që kur përdoret OOP zakonisht e bën pa shumë probleme, pasi procesi i ndryshimit ndikon në zonën lokale.

Ndryshimi i ndërfaqes gjithashtu nuk është një detyrë shumë e vështirë, por zgjidhja e saj mund të sjellë nevojën për të koordinuar proceset e ndërveprimit midis objekteve, gjë që do të kërkojë ndryshime në klasat e tjera të programit. Megjithatë, zvogëlimi i numrit të parametrave në ndërfaqe në krahasim me programimin modular e thjeshton shumë këtë proces.

Thjeshtësia e modifikimit e bën relativisht të lehtë përshtatjen e sistemeve softuerike me ndryshimin e kushteve të funksionimit, gjë që rrit jetëgjatësinë e sistemeve, zhvillimi i të cilave kërkon kohë dhe burime materiale të mëdha.

Faqe 9 nga 51

Parimet themelore të OOP

Një tipar i veçantë i OOP është se një objekt ose grup objektesh mund të zhvillohet veçmas, dhe, për rrjedhojë, dizajni i tyre mund të jetë në faza të ndryshme. Për shembull, klasat e ndërfaqes tashmë janë zbatuar, por struktura e klasave të domenit është ende duke u përmirësuar.

Në mënyrë tipike, dizajni fillon kur çdo fragment i fushës së temës përshkruhet mjaftueshëm plotësisht në procesin e analizës.

Ne do të fillojmë shqyrtimin tonë të teknikave bazë të qasjes së objektit me zbërthimin e objektit.

Zbërthimi i objektit

Siç u përmend më lart, kur përdorni teknologjinë OOP, zgjidhja paraqitet në formë rezultat i ndërveprimit të elementeve funksionale individuale një sistem që simulon proceset,

që ndodh në fushën lëndore të detyrës.

Në një sistem të tillë, çdo element funksional, pasi ka marrë disa ndikime hyrëse (të quajtur mesazh) në procesin e zgjidhjes së problemit,

kryen veprime të paracaktuara (për shembull, mund të ndryshojë gjendjen e vet, të kryejë disa llogaritje, të vizatojë një dritare ose grafik dhe nga ana tjetër të ndikojë në elementë të tjerë). Procesi i zgjidhjes së problemit kontrollohet nga sekuenca e mesazheve. Duke i kaluar këto mesazhe nga elementi në element, sistemi kryen veprimet e nevojshme.

Elementet funksionale të sistemit, parametrat dhe sjellja e të cilave përcaktohen nga gjendja e problemit dhe kanë sjellje të pavarur

(d.m.th., "aftë" për të kryer veprime të caktuara në varësi të mesazheve të marra dhe gjendjes së elementit) quhen objekte.

Quhet procesi i paraqitjes së domenit të problemit si një koleksion objektesh që shkëmbejnë mesazhe zbërthimi i objektit.

Faqe 10 nga 51

Parimet themelore të OOP

Për të kuptuar se cilat objekte dhe mesazhe diskutohen gjatë kryerjes së dekompozimit të objekteve në secilin rast specifik, duhet të mbahet mend se qasja e objektit fillimisht u propozua për zhvillimin e modeleve simuluese të sjelljes së sistemeve komplekse. Kompleti i objekteve të sistemeve të tilla zakonisht përcaktohet duke analizuar proceset e simuluara.

Shembull. Zbërthimi i objektit (modeli i simulimit

stacionet e benzinës). Le të na interesojë varësia e gjatësisë së radhës në një pikë karburanti nga numri i pikave të karburantit, parametrat e shërbimit të çdo pompe karburanti dhe intensiteti i kërkesave për karburant (ne po shqyrtojmë të njëjtin lloj karburanti).

Problemet e këtij lloji zakonisht zgjidhen duke përdorur modele simulimi. Modeli simulon në mënyrë programore një proces real me parametra të dhënë, duke regjistruar njëkohësisht karakteristikat e tij. Duke përsëritur shumë herë procesin e simulimit me vlera të ndryshme të parametrave të shërbimit ose marrjen e kërkesave, studiuesi merr vlera specifike të karakteristikave mbi të cilat janë ndërtuar grafikët e varësive të analizuara.

Procesi i funksionimit të një stacioni karburanti me tre pika karburanti mund të përfaqësohet në formën e një diagrami.

Nuk di të programoj në gjuhë të orientuara nga objekti. Unë nuk mësova. Pas 5 vitesh programimi industrial në Java, ende nuk di si të krijoj një sistem të mirë në një stil të orientuar nga objekti. Unë thjesht nuk e kuptoj.

Unë u përpoqa të mësoja, sinqerisht. Studiova modele, lexova kodin e projekteve me burim të hapur, u përpoqa të ndërtoj koncepte koherente në kokën time, por ende nuk i kuptova parimet e krijimit të programeve me cilësi të lartë të orientuar nga objekti. Ndoshta dikush tjetër i ka kuptuar, por jo unë.

Dhe këtu janë disa gjëra që më bëjnë konfuz.

Unë nuk e di se çfarë është OOP

Seriozisht. Është e vështirë për mua të formuloj idetë kryesore të OOP. Në programimin funksional, një nga idetë kryesore është pashtetësia. Në strukturore - zbërthimi. Në modulare, funksionaliteti ndahet në blloqe të plota. Në secilën prej këtyre paradigmave, parimet mbizotëruese zbatohen në 95% të kodit dhe gjuha është krijuar për të inkurajuar përdorimin e tyre. Unë nuk di ndonjë rregull të tillë për OOP.
  • Abstraksioni
  • Kapsulimi
  • Trashëgimia
  • Polimorfizmi
Duket si një grup rregullash, apo jo? Pra, këto janë rregullat që duhen ndjekur në 95% të rasteve? Hmm, le të hedhim një vështrim më të afërt.

Abstraksioni

Abstraksioni është një mjet i fuqishëm programimi. Kjo është ajo që na lejon të ndërtojmë sisteme të mëdha dhe të mbajmë kontrollin mbi to. Nuk ka gjasa që do t'i kishim afruar ndonjëherë nivelit të sotëm të programeve nëse nuk do të ishim të armatosur me një mjet të tillë. Sidoqoftë, si lidhet abstraksioni me OOP?

Së pari, abstraksioni nuk është një atribut ekskluzivisht i OOP, ose i programimit në përgjithësi. Procesi i krijimit të niveleve të abstraksionit shtrihet pothuajse në të gjitha fushat e njohurive njerëzore. Kështu, ne mund të bëjmë gjykime për materialet pa hyrë në detajet e strukturës së tyre molekulare. Ose flisni për objekte pa përmendur materialet nga të cilat janë bërë. Ose flisni për mekanizma komplekse, të tilla si një kompjuter, një turbinë avioni ose trupin e njeriut, pa kujtuar detajet individuale të këtyre entiteteve.

Së dyti, ka pasur gjithmonë abstraksione në programim, duke filluar nga shkrimet e Ada Lovelace, e cila konsiderohet si programuesja e parë në histori. Që atëherë, njerëzit kanë krijuar vazhdimisht abstraksione në programet e tyre, shpesh vetëm me mjetet më të thjeshta për këtë. Kështu, Abelson dhe Sussman, në librin e tyre të njohur, përshkruajnë se si të krijohet një sistem për zgjidhjen e ekuacioneve që mbështet numrat kompleks dhe madje edhe polinomet, duke përdorur vetëm procedura dhe lista të lidhura. Pra, çfarë mjetesh shtesë të abstraksionit ofron OOP? Unë nuk kam asnjë ide. Po ndahet kodi në nënprograme? Çdo gjuhë e nivelit të lartë mund ta bëjë këtë. Kombinoni rutinat në një vend? Ka mjaft module për këtë. Tipizimi? Ishte atje shumë kohë përpara PLO. Shembulli me një sistem për zgjidhjen e ekuacioneve tregon qartë se ndërtimi i niveleve të abstraksionit varet jo aq nga mjetet gjuhësore, por nga aftësitë e programuesit.

Kapsulimi

Avantazhi kryesor i kapsulimit është fshehja e zbatimit. Kodi i klientit sheh vetëm ndërfaqen dhe mund të mbështetet vetëm në të. Kjo liron zhvilluesit të cilët mund të vendosin të ndryshojnë zbatimin. Dhe kjo është vërtet e lezetshme. Por pyetja përsëri është, çfarë ka të bëjë OOP me të? Të gjitha Paradigmat e mësipërme përfshijnë fshehjen e zbatimit. Kur programoni në C, ju shpërndani ndërfaqen në skedarët e kokës, Oberon ju lejon të bëni fushat dhe metodat lokale në modul dhe së fundi, abstraksioni në shumë gjuhë ndërtohet thjesht përmes nënprogrameve që gjithashtu përmbledhin zbatimin. Për më tepër, gjuhët e orientuara nga objekti janë shpesh vetë shkelin rregullin e kapsulimit, duke siguruar qasje në të dhëna përmes metodave speciale - getters dhe setters në Java, pronat në C#, etj. (Në komentet zbuluam se disa objekte në gjuhët e programimit nuk janë objekte nga pikëpamja OOP: objektet e transferimit të të dhënave janë përgjegjëse vetëm për transferimin e të dhënave, dhe për këtë arsye nuk janë entitete OOP me të drejta të plota, dhe për këtë arsye nuk ka Nga ana tjetër, metodat e aksesorëve ruhen më së miri për të ruajtur fleksibilitetin arkitektonik. Për më tepër, disa gjuhë të orientuara drejt objekteve, si p.sh. Python, nuk përpiqen të fshehin asgjë. , por mbështetuni vetëm në inteligjencën e zhvilluesve që përdorin këtë kod.

Trashëgimia

Trashëgimia është një nga gjërat e pakta të reja që vërtet doli në skenë falë OOP. Jo, gjuhët e orientuara nga objekti nuk krijuan një ide të re - trashëgimia mund të zbatohet në çdo paradigmë tjetër - por OOP për herë të parë e solli këtë koncept në nivelin e vetë gjuhës. Përparësitë e trashëgimisë janë gjithashtu të dukshme: kur ju pothuajse të kënaqur me një klasë, mund të krijoni një pasardhës dhe të anashkaloni një pjesë të funksionalitetit të tij. Në gjuhët që mbështesin trashëgiminë e shumëfishtë, si C++ ose Scala (në këtë të fundit, përmes tipareve), shfaqet një rast tjetër përdorimi - mixins, klasa të vogla që ju lejojnë të "përzieni" funksionalitetin në një klasë të re pa kopjuar kodin.

Pra, kjo është ajo që e veçon OOP si një paradigmë nga të tjerët? Hmm... nëse po, pse e përdorim kaq rrallë në kod real? E mbani mend atë që thashë për 95% të kodit që u bindet rregullave të paradigmës dominuese? Nuk po bëja shaka. Në programimin funksional, të paktën 95% e kodit përdor të dhëna dhe funksione të pandryshueshme pa efekte anësore. Në modular, pothuajse i gjithë kodi është i paketuar logjikisht në module. Përkrahësit e programimit të strukturuar, duke ndjekur parimet e Dijkstra, përpiqen t'i ndajnë të gjitha pjesët e programit në pjesë të vogla. Trashëgimia përdoret shumë më rrallë. Ndoshta në 10% të kodit, ndoshta në 50%, në disa raste (për shembull, kur trashëgoni nga klasat e kornizës) - në 70%, por jo më shumë. Sepse në shumicën e situatave është e lehtë nuk ka nevojë.

Për më tepër, trashëgimia e rrezikshme për dizajn të mirë. Aq e rrezikshme sa Banda e Katërve (në dukje predikues të PLO) në librin e tyre rekomandojnë zëvendësimin e saj me delegim sa herë që është e mundur. Trashëgimia siç ekziston në gjuhët aktualisht të njohura çon në dizajn të brishtë. Pasi është trashëguar nga një paraardhës, një klasë nuk mund të trashëgohet më nga të tjerët. Ndryshimi i një paraardhësi gjithashtu bëhet i rrezikshëm. Ka, sigurisht, modifikues privatë/të mbrojtur, por ata gjithashtu kërkojnë aftësi të konsiderueshme psikike për të gjetur se si mund të ndryshojë klasa dhe si mund ta përdorë atë kodi i klientit. Trashëgimia është aq e rrezikshme dhe e papërshtatshme sa korniza të mëdha (siç janë Spring dhe EJB në Java) po e braktisin atë në favor të mjeteve të tjera jo të orientuara nga objekti (për shembull, metaprogramimi). Pasojat janë aq të paparashikueshme saqë disa biblioteka (të tilla si Guava) caktojnë modifikues në klasat e tyre që ndalojnë trashëgiminë dhe në gjuhën e re Go u vendos që të braktiset fare hierarkia e trashëgimisë.

Polimorfizmi

Ndoshta polimorfizmi është gjëja më e mirë për programimin e orientuar nga objekti. Falë polimorfizmit, kur del, një objekt i tipit Person duket si "Shandorkin Adam Impolitovich", dhe një objekt i tipit Point duket si "". Është kjo që ju lejon të shkruani "Mat1 * Mat2" dhe të merrni produktin e matricave, të ngjashëm me produktin e numrave të zakonshëm. Pa të, nuk do të ishte e mundur të lexoheshin të dhënat nga rryma hyrëse, pa u kujdesur nëse ato vijnë nga rrjeti, një skedar ose një linjë në memorie. Kudo që ka ndërfaqe, nënkuptohet edhe polimorfizmi.

Më pëlqen shumë polimorfizmi. Prandaj, nuk do të flas as për problemet e tij në gjuhët kryesore. Unë gjithashtu do të hesht për ngushtësinë e qasjes së dërgimit vetëm sipas llojit dhe se si mund të bëhet kjo. Në shumicën e rasteve funksionon ashtu siç duhet, gjë që nuk është keq. Pyetja është: a është polimorfizmi vetë parimi që e dallon OOP nga paradigmat e tjera? Nëse do të më kishit pyetur mua (dhe duke qenë se po e lexoni këtë tekst, mund të supozoni se keni pyetur), unë do të përgjigjesha "jo". Dhe arsyeja është ende e njëjta përqindje e përdorimit në kod. Ndoshta ndërfaqet dhe metodat polimorfike janë pak më të zakonshme se trashëgimia. Por krahasoni numrin e rreshtave të kodit që ata zënë me numrin e rreshtave të shkruar në stilin e zakonshëm procedural - ka gjithmonë më shumë nga këto të fundit. Duke parë gjuhët që inkurajojnë këtë stil programimi, nuk do t'i quaja polimorfike. Gjuhët që mbështesin polimorfizmin - po, kjo është normale. Por jo gjuhë polimorfike.

(Megjithatë, ky është mendimi im. Gjithmonë mund të mos pajtoheni.)

Pra, abstraksioni, kapsulimi, trashëgimia dhe polimorfizmi - e gjithë kjo është në OOP, por asnjë nga këto nuk është një atribut integral i saj. Atëherë çfarë është OOP? Ekziston një mendim se thelbi i programimit të orientuar nga objekti qëndron në objekte (tingëllon mjaft logjike) dhe klasa. Është ideja e kombinimit të kodit dhe të dhënave, dhe ideja që objektet në një program pasqyrojnë entitete në botën reale. Ne do t'i kthehemi këtij mendimi më vonë, por së pari le të vendosim disa i.

OOP i kujt është më i freskët?

Nga pjesa e mëparshme është e qartë se gjuhët e programimit mund të ndryshojnë shumë në mënyrën se si zbatojnë programimin e orientuar nga objekti. Nëse merrni tërësinë e të gjitha zbatimeve të OOP në të gjitha gjuhët, atëherë ka shumë të ngjarë që nuk do të gjeni një veçori të vetme të përbashkët për të gjitha. Për të kufizuar disi këtë kopsht zoologjik dhe për të sqaruar arsyetimin, do të përqendrohem vetëm në një grup - gjuhët thjesht të orientuara nga objekti, përkatësisht Java dhe C#. Termi "thjesht i orientuar nga objekti" në këtë rast do të thotë që gjuha nuk mbështet paradigma të tjera ose i zbaton ato përmes të njëjtit OOP. Python ose Ruby, për shembull, nuk do të jenë të pastër, sepse ju lehtë mund të shkruani një program të plotë mbi to pa një deklaratë të vetme klase.

Për të kuptuar më mirë thelbin e OOP në Java dhe C#, le të shohim shembuj të zbatimit të kësaj paradigme në gjuhë të tjera.

Muhabet. Ndryshe nga homologët e saj modernë, kjo gjuhë u shtyp në mënyrë dinamike dhe përdori një stil të kalimit të mesazheve për të zbatuar OOP. Në vend të thirrjes së metodave, objektet i dërgonin mesazhe njëri-tjetrit dhe nëse marrësi nuk mund të përpunonte atë që vinte, ai thjesht ia përcjell mesazhin dikujt tjetër.

Lisp e zakonshme. Fillimisht, CL ndoqi të njëjtën paradigmë. Më pas, zhvilluesit vendosën që shkrimi "(send obj "some-message)" ishte shumë i gjatë dhe e konvertuan shënimin në një thirrje metode - "(disome-metod obj)" Sot, Common Lisp ka një sistem programimi të pjekur të orientuar nga objekti ( CLOS) me mbështetje për trashëgimi të shumëfishtë, shumë metoda dhe metaklasa Një tipar dallues është se OOP në CL nuk rrotullohet rreth objekteve, por rreth funksioneve të përgjithshme.

Clojure. Clojure ka 2 sisteme programimi të orientuara nga objekti - një i trashëguar nga Java, dhe i dyti, i bazuar në multimetoda dhe më shumë i ngjashëm me CLOS.

R. Kjo gjuhë për analizën e të dhënave statistikore ka gjithashtu 2 sisteme programimi të orientuara drejt objekteve - S3 dhe S4. Të dyja janë trashëguar nga gjuha S (gjë që nuk është për t'u habitur, duke pasur parasysh se R është një zbatim me kod të hapur i S komercial). S4 përputhet kryesisht me implementimet OOP në gjuhët moderne të zakonshme. S3 është një opsion më i lehtë, i zbatuar thjesht duke përdorur vetë gjuhën: krijohet një funksion i përgjithshëm që dërgon kërkesat bazuar në atributin "klasë" të objektit të marrë.

JavaScript. Ideologjikisht i ngjashëm me Smalltalk, megjithëse përdor një sintaksë të ndryshme. Në vend të trashëgimisë, ai përdor prototipin: nëse vetia e dëshiruar ose metoda e thirrur nuk është në vetë objektin, atëherë kërkesa i kalohet objektit prototip (vetia e prototipit të të gjitha objekteve JavaScript). Një fakt interesant është se sjellja e të gjitha objekteve të klasës mund të ndryshohet duke zëvendësuar një nga metodat prototip (për shembull, shtimi i metodës `.toBASE64` për klasën string duket shumë bukur).

Python. Në përgjithësi, ai ndjek të njëjtin koncept si gjuhët kryesore, por gjithashtu mbështet kalimin e kërkimit të atributeve në një objekt tjetër, si në JavaScript ose Smalltalk.

Haskell. Në Haskell nuk ka fare gjendje, dhe për këtë arsye nuk ka objekte në kuptimin e zakonshëm. Megjithatë, ekziston ende një lloj OOP atje: llojet e të dhënave mund t'i përkasin një ose më shumë klasave të tipit. Për shembull, pothuajse të gjitha llojet në Haskell janë në klasën Eq (përgjegjës për operacionet e krahasimit midis 2 objekteve), dhe të gjithë numrat janë gjithashtu në klasat Num (veprimet mbi numrat) dhe Ord (veprimet mbi numrat).<, <=, >=, >). Në gjuhët menstruale, llojet korrespondojnë me klasat (të dhënat), dhe klasat e tipit korrespondojnë me ndërfaqet.

Shtet apo pa shtetësi?

Por le të kthehemi te sistemet më të zakonshme të programimit të orientuar drejt objektit. Ajo që nuk mund ta kuptoja kurrë është marrëdhënia e objekteve me gjendjen e brendshme. Përpara se të studioja OOP, gjithçka ishte e thjeshtë dhe transparente: ka struktura që ruajnë disa të dhëna të lidhura, ka procedura (funksione) që i përpunojnë ato. ec (qen), tërheq (llogari, shuma). Pastaj erdhën objektet, dhe kjo ishte gjithashtu në rregull (megjithëse leximi i programeve u bë shumë më i vështirë - qeni im po ecte [kush?], dhe llogaria po tërhiqte para [nga ku?]). Pastaj mësova për fshehjen e të dhënave. Unë ende mund ta shëtisja qenin, por nuk mund të shikoja më përbërjen e ushqimit të tij. Ushqimi nuk bëri asgjë (ju ndoshta mund të shkruani food.eat(qen), por unë ende preferoj që qeni im të hajë ushqim dhe jo anasjelltas). Ushqimi është vetëm të dhëna, dhe unë (dhe qeni im) thjesht duhej t'i qasja. Të gjitha Vetëm. Por nuk ishte më e mundur të futej në kornizën e paradigmës, si në xhinse të vjetra nga fundi i viteve '90.

Mirë, ne kemi metoda të aksesit të të dhënave. Le të kënaqemi me këtë vetë-mashtrim të vogël dhe të pretendojmë se të dhënat tona janë vërtet të fshehura. Por tani e di që objektet janë, para së gjithash, të dhëna, dhe më pas, ndoshta, metoda që i përpunojnë ato. Kuptova se si të shkruaja programe, për çfarë të përpiqesha gjatë dizajnimit.

Përpara se të kisha kohë për të shijuar ndriçimin, pashë fjalën pa shtetësi në internet (të betohem se ishte e rrethuar nga shkëlqimi dhe një aureolë varej mbi shkronjat t dhe l). Një studim i shkurtër i literaturës zbuloi botën e mrekullueshme të rrjedhës së kontrollit transparent dhe multithreading-ut të thjeshtë pa nevojën për të gjurmuar konsistencën e objektit. Sigurisht, menjëherë doja të prekja këtë botë të mrekullueshme. Sidoqoftë, kjo nënkuptonte një refuzim të plotë të çdo rregulli - tani nuk ishte e qartë nëse qeni duhet të ecte vetë, apo nëse ishte i nevojshëm një Menaxher i veçantë Walk për këtë; a keni nevojë për një llogari, apo do të merret Banka me të gjitha punët, dhe nëse po, a duhet t'i shlyejë paratë në mënyrë statike apo dinamike, etj. Numri i rasteve të përdorimit është rritur në mënyrë eksponenciale dhe të gjitha rastet e përdorimit të ardhshëm mund të çojnë në nevojën për rifaktorim të madh.

Unë ende nuk e di se kur një objekt duhet të bëhet pa shtetësi, kur duhet të jetë me status dhe kur duhet të jetë thjesht një kontejner të dhënash. Ndonjëherë është e qartë, por në shumicën e rasteve nuk është.

Shtypja: statike apo dinamike?

Një gjë tjetër që nuk mund të vendos për gjuhët si C# dhe Java është nëse ato janë të shtypura në mënyrë statike apo dinamike. Shumica e njerëzve ndoshta do të thërrasin: “Çfarë marrëzie! Natyrisht i shtypur në mënyrë statike! Llojet kontrollohen në kohën e përpilimit! Por a është vërtet kaq e thjeshtë? A është e vërtetë që duke specifikuar tipin X në parametrat e një metode, një programues mund të jetë i sigurt se objektet e tipit X do t'i kalohen gjithmonë atij? Kjo është e drejtë - nuk mundet, sepse ... do të jetë e mundur të kalohet një parametër i tipit X në metodën X ose trashëgimtari i tij. Do të duket, pra çfarë? Pasardhësit e klasës X do të kenë ende të njëjtat metoda si X. Metodat janë metoda, por logjika e punës mund të dalë krejtësisht e ndryshme. Rasti më i zakonshëm është kur një klasë fëmijësh rezulton të jetë e optimizuar për nevoja të tjera përveç X, dhe metoda jonë mund të mbështetet pikërisht në atë optimizim (nëse një skenar i tillë ju duket jorealist, provoni të shkruani një shtojcë për një bibliotekë të zhvilluar me burim të hapur - ose do të kaloni disa javë për të analizuar arkitekturën dhe algoritmet e bibliotekës, ose thjesht do të thërrisni metoda me një nënshkrim të përshtatshëm rastësisht). Si rezultat, programi funksionon, por shpejtësia e funksionimit bie me një rend të madhësisë. Edhe pse nga këndvështrimi i përpiluesit gjithçka është e saktë. Është domethënëse që Scala, e cila quhet pasardhëse e Java-s, në shumë vende si parazgjedhje lejon që të kalohen vetëm argumentet e llojit të specifikuar, megjithëse kjo sjellje mund të ndryshohet.

Një problem tjetër është vlera null, e cila mund të kalohet në vend të pothuajse çdo objekti në Java dhe në vend të çdo objekti Nullable në C#. null u përket të gjitha llojeve në të njëjtën kohë, dhe në të njëjtën kohë nuk i përket asnjërit. null nuk ka as fusha as metoda, kështu që çdo thirrje në të (përveç kontrollit për null) rezulton në një gabim. Duket se të gjithë janë mësuar me këtë, por për krahasim, Haskell (dhe e njëjta Scala) është e detyruar të përdorë lloje të veçanta (Ndoshta në Haskell, Option në Scala) për të mbështjellë funksione që në gjuhë të tjera mund të kthejnë nule. Si rezultat, ata shpesh thonë për Haskell "është e vështirë të përpilosh një program në të, por nëse ke sukses, atëherë ka shumë të ngjarë që ai të funksionojë siç duhet".

Nga ana tjetër, gjuhët e zakonshme nuk janë të shtypura në mënyrë dinamike, dhe për këtë arsye nuk kanë veti të tilla si ndërfaqe të thjeshta dhe procedura fleksibël. Si rezultat, të shkruarit në stilin Python ose Lisp gjithashtu bëhet i pamundur.

Çfarë ndryshimi ka si quhet ky shtypje nëse dihen gjithsesi të gjitha rregullat? Dallimi është se nga cila anë i afroheni dizajnit të arkitekturës. Ekziston një debat i gjatë se si të ndërtohet një sistem: të bëhen shumë lloje dhe pak funksione, apo pak lloje dhe shumë funksione? Qasja e parë përdoret në mënyrë aktive në Haskell, e dyta në Lisp. Gjuhët moderne të orientuara nga objekti përdorin diçka në mes. Nuk dua të them se kjo është e keqe - ndoshta ka avantazhet e saj (në fund të fundit, nuk duhet të harrojmë se Java dhe C# janë platforma shumë-gjuhëshe), por sa herë që filloj një projekt të ri pyes veten se ku të filloj projektim - me lloje ose nga funksionaliteti.

Dhe më tej...

Nuk di si ta modeloj problemin. Besohet se OOP ju lejon të shfaqni objekte të botës reale në një program. Sidoqoftë, në realitet unë kam një qen (me dy veshë, katër putra dhe një jakë) dhe një llogari bankare (me një menaxher, nëpunës dhe një pushim dreke), dhe në program - WalkManager, AccountFactory ... mirë, ju merrni Ideja. Dhe çështja nuk është se programi ka klasa ndihmëse që nuk pasqyrojnë objekte të botës reale. Fakti është se kontrolloni ndryshimet e rrjedhës. WalkingManager po më grabit gëzimin për të ecur me qenin tim dhe unë marr para nga një llogari bankare pa shpirt (hej, ku është ajo vajza e lezetshme që kam ndërruar para javën e kaluar?).

Ndoshta unë jam snob, por isha shumë më i lumtur kur të dhënat në kompjuter ishin vetëm të dhëna, edhe nëse përshkruanin qenin tim ose një llogari bankare. Mund të bëja atë që ishte e përshtatshme me të dhënat, pa marrë parasysh botën reale.

Unë gjithashtu nuk e di se si ta zbërthej siç duhet funksionalitetin. Në Python ose C++, nëse më duhej një funksion i vogël për të kthyer një varg në një numër, thjesht e shkruajta në fund të skedarit. Në Java ose C# jam i detyruar ta vendos në një klasë të veçantë StringUtils. Në gjuhët para-OO, mund të deklaroja një mbështjellës ad hoc për të kthyer dy vlera nga një funksion (shuma e tërhequr dhe bilanci i llogarisë). Në gjuhët OOP, do të më duhet të krijoj një klasë të plotë të Rezultateve të Transaksionit. Dhe për një person të ri në projekt (ose edhe për veten time një javë më vonë), kjo klasë do të duket po aq e rëndësishme dhe themelore në arkitekturën e sistemit. 150 skedarë, dhe të gjithë po aq të rëndësishëm dhe themelorë - oh po, arkitekturë transparente, nivele të mrekullueshme abstraksioni.

Nuk di të shkruaj programe efikase. Programet efikase përdorin pak memorie - përndryshe mbledhësi i mbeturinave do të ngadalësojë vazhdimisht ekzekutimin. Por për të kryer operacionin më të thjeshtë në gjuhët e orientuara nga objekti, duhet të krijoni një duzinë objektesh. Për të bërë një kërkesë HTTP, më duhet të krijoj një objekt të tipit URL, më pas një objekt të tipit HttpConnection, më pas një objekt të tipit Kërkesë... mirë, e kuptoni idenë. Në programimin procedural, unë thjesht do të quaj disa procedura, duke i kaluar atyre një strukturë të krijuar në stack. Me shumë mundësi, vetëm një objekt do të krijohej në memorie - për të ruajtur rezultatin. Në OOP, më duhet të rrëmoj kujtesën gjatë gjithë kohës.

Ndoshta OOP është një paradigmë vërtet e bukur dhe elegante. Ndoshta nuk jam aq i zgjuar sa ta kuptoj. Ndoshta ka dikush atje që mund të krijojë një program vërtet të bukur në një gjuhë të orientuar nga objekti. Epo, unë vetëm mund t'i kem zili.

Për shumë programues PHP, programimi i orientuar nga objekti është një koncept frikësues, i mbushur me sintaksë komplekse dhe pengesa të tjera për zotërimin. Në këtë artikull koncepti programimi i orientuar nga objekti(OOP) përfaqësohet si një stil kodimi që ju lejon të gruponi aktivitetet e ndërlidhura në klasa për të krijuar kode më kompakte dhe efikase.

Çfarë është programimi i orientuar nga objekti

Programimi i orientuar nga objekti është një stil kodimi që lejon një zhvillues të grupojë detyra të ngjashme klasat. Kështu, kodi përputhet me parimin DRY (mos e përsërit veten) dhe bëhet i lehtë për t'u mirëmbajtur.

Një nga avantazhet e programimit DRY është se nëse disa informacione kërkojnë që ju të ndryshoni programin tuaj, atëherë ju duhet ndryshoni kodin vetëm në një vend për të përditësuar algoritmin. Një nga makthet më të këqija të një zhvilluesi është ruajtja e kodit që deklaron të dhënat vazhdimisht, duke e bërë çdo ndryshim në program një lojë të pafund të fshehjes dhe kërkimit ndërsa gjurmoni të dhëna të kopjuara dhe pjesë algoritmi.

OOP frikëson shumë zhvillues sepse prezanton sintaksë të re dhe, në shikim të parë, duket më kompleks se kodimi i thjeshtë procedural. Sidoqoftë, pas një inspektimi më të afërt, OOP është në fakt një qasje shumë e qartë dhe jashtëzakonisht e thjeshtë për programimin.

Cilat janë objektet dhe klasat

Para se të zhyteni në përkufizimet e qarta të OOP, është e nevojshme të keni një kuptim themelor të ndryshimit midis tyre klasat Dhe objektet. Ky seksion i artikullit do t'ju ndihmojë të merrni një ide për klasat, aftësitë e tyre të ndryshme dhe disa aplikacione.

Cili është ndryshimi midis klasave dhe objekteve

Zhvilluesit, duke filluar të flasin për klasa dhe objekte, fillojnë të zëvendësojnë konceptet. Fatkeqësisht, kjo ndodh shumë shpesh.

Një klasë, për shembull, është Projekti i shtëpisë. Ai përcakton në letër se si do të duket shtëpia, përshkruan qartë të gjitha marrëdhëniet midis pjesëve të ndryshme të saj, edhe nëse shtëpia nuk ekziston në realitet.

Dhe objekti është shtëpi e vërtetë, e cila është ndërtuar në përputhje me projektin. Të dhënat që ruhen në një objekt janë si druri, telat dhe betoni që përbëjnë një shtëpi: pa montim sipas dizajnit, do të jetë vetëm një grumbull materialesh. Megjithatë, kur bashkohen ata bëjnë një shtëpi të shkëlqyer dhe të rehatshme.

Klasat formojnë një strukturë të dhënash dhe veprimesh dhe e përdorin këtë informacion për të ndërtuar objekte. Më shumë se një objekt mund të ndërtohet nga një klasë në të njëjtën kohë, secili prej tyre do të jetë i pavarur nga të tjerët. Duke vazhduar analogjinë me ndërtimin, një lagje e tërë mund të ndërtohej sipas një projekti: 150 shtëpi të ndryshme që duken njësoj, por secila prej tyre strehon familje të ndryshme dhe dekorimi i brendshëm i ndërtesave është i ndryshëm.

Struktura e klasës

Sintaksa për krijimin e një klase është shumë e thjeshtë: për të deklaruar një klasë, përdorni fjalën kyçe të klasës, e ndjekur nga emri i klasës dhe një grup kllapash kaçurrelë (()):

Pas krijimit të një klase, një objekt i ri mund të instantohet dhe të ruhet në një variabël duke përdorur fjalën kyçe të re:

$obj = Klasa e re My;

Për të parë përmbajtjen e një objekti, përdorni var_dump():

Var_dump($obj);

Ju mund ta provoni të gjithë procesin duke kopjuar të gjithë kodin në skedarin test.php:

Ngarkoni faqen në shfletuesin tuaj dhe linja e mëposhtme duhet të shfaqet në ekran:

Objekti(MyClass)#1 (0) ( )

Sapo keni krijuar skriptin tuaj të parë OOP.

Përcaktimi i vetive të klasës

Vetitë, ose variablat e klasës, përdoren për të shtuar të dhëna në një klasë. Vetitë funksionojnë si variabla të rregullt, por ato janë të lidhura me një objekt dhe mund të arrihen vetëm duke përdorur objektin.

Për të shtuar vetitë në klasën MyClass, përdorni këtë kod në skriptin tuaj:

Fjala kyçe publike përcakton dukshmërinë e një vetie, të cilën do ta trajtojmë më vonë në këtë kapitull. Vetia më pas emërohet duke përdorur sintaksë normale të ndryshores dhe i caktohet një vlerë (edhe pse një veti e klasës nuk ka nevojë të inicializohet).

Echo $obj->prop1;

Meqenëse mund të ketë zbatime të shumta të një klase, pa referencë në një objekt specifik, vetia nuk mund të lexohet sepse skripti nuk mund të përcaktojë se nga cili objekt të lexohet. Një shigjetë (->) është një konstrukt OOP që përdoret për të hyrë në vetitë dhe metodat e një objekti të caktuar.

Ndryshoni skriptin në test.php për të lexuar vlerën e pronës në vend që të shfaqni informacione për të gjithë klasën:

mbështetëse1; // Shfaq pronën?>

Rifresko faqen në shfletuesin tuaj për të parë rezultatin e skriptit:

Pronë e klasës

Përcaktimi i metodave të klasës

Metodaështë një funksion i klasës. Një veprim individual që një objekt mund të kryejë përcaktohet në një klasë si metodë.

Për shembull, le të krijojmë metoda që vendosin dhe lexojnë vlerën e vetive $prop1:

prop1 = $newval; ) funksioni publik getProperty() (kthimi $this->prop1 . "
"; ) ) $obj = MyClass i ri; echo $obj->prop1; ?>

shënim- OOP lejon një objekt t'i referohet vetes duke përdorur $this . Kur punoni brenda një metode, përdorimi i $this ju lejon të përdorni emrin e objektit jashtë klasës.

Për të përdorur një metodë, thirreni atë si një funksion të rregullt, por fillimisht specifikoni objektin të cilit i përket. Ne lexojmë pronën nga MyClass, ndryshojmë vlerën, lexojmë përsëri:

prop1 = $newval; ) funksioni publik getProperty() (kthimi $this->prop1 . "
"; ) ) $obj = "Klasa e re" e My; () ; // Lexoni përsëri vlerën për të parë ndryshimet?>

Ne rifreskojmë faqen në shfletues dhe shohim sa vijon:

Pronë e klasës Pronë e re

Përfitimet e OOP vijnë në lojë kur përdoren objekte të shumta të së njëjtës klasë.

prop1 = $newval; ) funksioni publik getProperty() (kthimi $this->prop1 . "
"; ) ) // Krijo dy objekte $obj = MyClass i ri; $obj2 = MyClass i ri; // Merrni vlerat e $prop1 nga të dy objektet echo $obj->getProperty(); echo $obj2->getProperty( // Vendos vlerat e reja të vetive për të dy objektet $obj->setProperty("Vlera e re e pronës"); për të dy echo $obj->getProperty() ;

Kur ngarkoni faqen në shfletues, do të shihni sa vijon:

Vetia e klasës Vetia e klasës Vlera e re e pronës Prona i përket objektit të dytë

Shënim, OOP ruan objektet si entitete të ndryshme, duke e bërë të lehtë ndarjen e kodit në pjesë të ndryshme të vogla dhe të ndërlidhura.

Metodat magjike në OOP

Për ta bërë më të lehtë përdorimin e objekteve, PHP ka disa metodat magjike. Këto janë metoda të veçanta që thirren kur kryhen veprime të caktuara në një objekt. Në këtë mënyrë, një zhvillues mund të kryejë disa detyra të zakonshme me lehtësi relative.

Përdorimi i Konstruktorëve dhe Destruktorëve

Kur krijohet një objekt, shpesh është e nevojshme që disa veçori të vendosen menjëherë. Për të kryer detyra të tilla, PHP ka një metodë magjike __construct() që thirret automatikisht kur krijohet një objekt i ri.

Për të ilustruar konceptin, le të shtojmë një konstruktor në klasën MyClass. Do të printojë një mesazh kur krijohet një objekt i ri i klasës:

"; ) funksioni publik setProperty($newval) ($this->prop1 = $newval; ) funksioni publik getProperty() (kthimi $this->prop1 ."
"; ) ) // Krijo një objekt të ri $obj = MyClass i ri; // Merr vlerën e vetive $prop1 echo $obj->
"; ?>

shënim— konstanta __CLASS__ kthen emrin e klasës në të cilën quhet; kjo është një nga konstantat magjike të PHP.

Është krijuar një objekt i klasës "MyClass"! Fundi i pronës së klasës së skedarit.

Për të thirrur një funksion gjatë procesit të fshirjes së një objekti, përdorni metodën magjike __destruct(). Kjo është një metodë shumë e dobishme për pastrimin e duhur të vetive të klasës (për shembull, për të mbyllur siç duhet një lidhje të bazës së të dhënave).

Ne do të shfaqim një mesazh kur një objekt i klasës fshihet duke përdorur metodën magjike:
__destruct() në MyClass:

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksioni publik setProperty($newval) ($this->prop1 = $newval; ) funksioni publik getProperty() (kthimi $this->prop1 ."
"; ) ) // Krijo një objekt të ri $obj = i ri MyClass; // Merr vlerën e vetive $prop1 echo $obj->getProperty(); // Shfaq një mesazh për arritjen e fundit të skedarit echo "Fund e dosjes.
"; ?>

Ne rifreskojmë faqen në shfletues dhe marrim rezultatin:

Është krijuar një objekt i klasës "MyClass"! Fundi i pronës së klasës së skedarit. Objekti i klasës "MyClass" është fshirë.

Kur të arrihet fundi i skedarit, PHP lëshon automatikisht të gjitha burimet.

Për të thirrur në mënyrë të qartë një destruktor dhe për të hequr një objekt, mund të përdorni funksionin unset():


"; ) funksioni publik setProperty($newval) ($this->prop1 = $newval; ) funksioni publik getProperty() (kthimi $this->prop1 ."
"; ) ) // Krijo një objekt të ri $obj = MyClass i ri; // Merr vlerën e vetive $prop1 echo $obj->getProperty(); // Fshi objektin unset($obj); // Shfaq një mesazh për arritjen në fund të skedarit jehonë "Fundi i skedarit.
"; ?>

Tani rezultati i kodit do të duket si ky pas ngarkimit në shfletues:

Është krijuar një objekt i klasës "MyClass"! Vetia e klasës Objekti i klasës "MyClass" është fshirë. Fundi i dosjes.

Konverto në varg

Për të shmangur një gabim nëse skripti përpiqet të nxjerrë MyClass si një varg, përdoret një metodë tjetër magjike, __toString().

Pa përdorur __toString() Përpjekja për të nxjerrë një objekt si varg do të rezultojë në një gabim fatal. Provoni të përdorni funksionin echo për të nxjerrë një objekt pa përdorur magji:

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksioni publik setProperty($newval) ($this->prop1 = $newval; ) funksioni publik getProperty() (kthimi $this->prop1 ."

"; ?>

Rezultati do të duket si ky:

Është krijuar një objekt i klasës "MyClass"! Gabim fatal i kapshëm: Objekti i klasës MyClass nuk mund të konvertohej në varg në /Applications/XAMPP/xamppfiles/htdocs/testing/test.php në linjën 40

Për të shmangur gabimin, përdorni metodën __toString():

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksioni publik __toString() ( echo "Përdor metodën toString: "; ktheje $this->getProperty(); ) funksion publik setProperty($newval) ( $this->prop1 = $newval; ) funksion publik getProperty( ) ( ktheni $this->prop1 . "
"; ) ) // Krijo një objekt të ri $obj = myClass i ri; // Nxjerr objektin si jehonë vargu $obj; // Fshi objektin unset($obj); // Nxjerr një mesazh për arritjen e fundit të jehona e skedarit "Fundi i skedarit.
"; ?>

Në këtë rast, përpjekja për të kthyer një objekt në një varg do të rezultojë në një thirrje në metodën getProperty(). Ngarkoni skriptin në shfletues dhe shikoni rezultatin:

Është krijuar një objekt i klasës "MyClass"! Ne përdorim metodën toString: Vetia e klasës Objekti i klasës "MyClass" është fshirë. Fundi i dosjes.

Përdorimi i trashëgimisë së klasës

Klasat mund të trashëgojnë metoda dhe veti nga klasa të tjera duke përdorur fjalën kyçe zgjat. Për shembull, le të krijojmë një klasë të dytë që zgjeron MyClass dhe shton një metodë:

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksioni publik __toString() ( echo "Përdor metodën toString: "; ktheje $this->getProperty(); ) funksion publik setProperty($newval) ( $this->prop1 = $newval; ) funksion publik getProperty( ) ( ktheni $this->prop1 . "
"; ) ) klasa MyOtherClass zgjeron MyClass (funksioni publik newMethod() (jehonë "Nga metoda e klasës së re " . __CLASS__ .".
"; ) ) // Krijoni një objekt të ri $newobj = MyOtherClass i ri; // Përdorni metodën e re echo $newobj->newMethod(); // Përdorni metodën nga klasa mëmë echo $newobj->getProperty(); ? >

Pas ngarkimit të skriptit në shfletues, marrim rezultatin:

Është krijuar një objekt i klasës "MyClass"! Nga metoda e re e klasës "MyOtherClass". Vetia e klasës Objekti i klasës "MyClass" është fshirë.

Mbingarkimi i vetive dhe metodave të trashëguara

Për të ndryshuar sjelljen e vetive ose metodave ekzistuese në një klasë të re, thjesht mund t'i mbingarkoni ato duke i rideklaruar në klasën e re:

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksioni publik __toString() ( echo "Përdor metodën toString: "; ktheje $this->getProperty(); ) funksion publik setProperty($newval) ( $this->prop1 = $newval; ) funksion publik getProperty( ) ( ktheni $this->prop1 . "
"; ) ) klasa MyOtherClass zgjeron MyClass (funksioni publik __construct() (echo "New constructor in class " . __CLASS__ .".

"; ) ) // Krijo një objekt të ri $newobj = MyOtherClass i ri; // Nxjerr objektin si jehonë vargu $newobj->newMethod(); // Përdor metodën nga klasa prind echo $newobj->getProperty() ?>

Ndryshimet do të prodhojnë daljen e mëposhtme kur ekzekutoni kodin:

Konstruktor i ri në klasën "MyOtherClass". Nga metoda e re e klasës "MyOtherClass". Vetia e klasës Objekti i klasës "MyClass" është fshirë.

Ruajtja e funksionalitetit origjinal kur mbingarkohen metodat

Për të shtuar funksionalitet të ri në një metodë të trashëguar duke ruajtur funksionalitetin e metodës origjinale, përdorni fjalën kyçe prind me operatori i zgjidhjes së dukshmërisë ( :: ) :

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksioni publik __toString() ( echo "Përdor metodën toString: "; ktheje $this->getProperty(); ) funksion publik setProperty($newval) ( $this->prop1 = $newval; ) funksion publik getProperty( ) ( ktheni $this->prop1 . "
"; ) ) klasa MyOtherClass zgjeron MyClass ( funksion publik __construct() ( prind::__construct(); // Thirr konstruktorin e klasës prind echo "Ndërtues i ri në klasën " . __CLASS__ .".
"; ) funksioni publik newMethod() (echo "Nga një metodë e re e klasës" . __CLASS__ . ".
"; ) ) // Krijo një objekt të ri $newobj = MyOtherClass i ri; // Nxjerr objektin si jehonë vargu $newobj->newMethod(); // Përdor metodën nga klasa prind echo $newobj->getProperty() ?>

Kodi i mësipërm, kur të ekzekutohet, do të shfaqë mesazhe nga të dy konstruktorët e klasës së re dhe prind:

Është krijuar një objekt i klasës "MyClass"! Konstruktor i ri në klasën "MyOtherClass". Nga metoda e re e klasës "MyOtherClass". Vetia e klasës Objekti i klasës "MyClass" është fshirë.

Përcaktimi i fushës së vetive dhe metodave

Për kontroll shtesë mbi objektet, metodat dhe vetitë, është vendosur një fushëveprimi. Kjo kontrollon se si dhe nga ku mund të aksesohen pronat dhe metodat. Ekzistojnë tre fjalë kyçe për vendosjen e fushëveprimit: publike, e mbrojtur dhe private. Përveç vendosjes së fushës së veprimit, metodat dhe vetitë mund të deklarohen statike, duke i lejuar ato të aksesohen pa zbatuar klasën.

shënim- Scope është një veçori e re që u prezantua në PHP 5. Për pajtueshmërinë OOP me PHP 4, shihni manualin PHP.

Vetitë dhe metodat publike (Të Përgjithshme)

Të gjitha vetitë dhe metodat që keni përdorur më parë në këtë artikull ishin publike. Kjo do të thotë se ato mund të aksesohen kudo, brenda dhe jashtë klasës.

Metodat dhe vetitë e mbrojtura

Kur një pronë ose metodë deklarohet me një direktivë të mbrojtur, mund të aksesohet vetëm brenda vetë klasës ose brenda klasave të derivuara(klasat që zgjerojnë një klasë bazë që përmban një metodë me një direktivë të mbrojtura).

Le të deklarojmë metodën getProperty() si të mbrojtura në MyClass dhe përpiquni ta aksesoni atë jashtë klasës:

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksion publik __toString() ( echo "Përdor metodën toString: "; ktheje $this->getProperty(); ) funksion publik setProperty($newval) ( $this->prop1 = $newval; ) funksioni i mbrojtur getProperty( ) ( ktheni $this->prop1 . "

"; ) funksioni publik newMethod() (echo "Nga një metodë e re e klasës" . __CLASS__ . ".
"; ) ) // Krijo një objekt të ri $newobj = MyOtherClass i ri; // Provoni të thërrisni metodën e mbrojtur echo $newobj->getProperty(); ?>

Kur përpiqeni të ekzekutoni skriptin, do të gjenerohet gabimi i mëposhtëm:

Është krijuar një objekt i klasës "MyClass"! Konstruktor i ri në klasën "MyOtherClass". Gabim fatal: Thirrje në metodën e mbrojtur MyClass::getProperty() nga konteksti "" në /Applications/XAMPP/xamppfiles/htdocs/testing/test.php në linjën 55

Tani, le të krijojmë një metodë të re në MyOtherClass për të thirrur metodën getProperty():

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksion publik __toString() ( echo "Përdor metodën toString: "; ktheje $this->getProperty(); ) funksion publik setProperty($newval) ( $this->prop1 = $newval; ) funksioni i mbrojtur getProperty( ) ( ktheni $this->prop1 . "
"; ) ) klasa MyOtherClass zgjeron MyClass (funksioni publik __construct() ( prind::__construct(); echo "Ndërtues i ri në klasë " . __CLASS__ .".
"; ) funksioni publik newMethod() (echo "Nga një metodë e re e klasës" . __CLASS__ . ".
"; ) funksioni publik callProtected() ( return $this->getProperty(); ) ) // Krijo një objekt të ri $newobj = MyOtherClass i ri; // Thirr një metodë të mbrojtur nga një metodë publike echo $newobj->callProtected() ?>

Kur ekzekutoni skriptin, rezultati do të jetë si ky:

Është krijuar një objekt i klasës "MyClass"! Konstruktor i ri në klasën "MyOtherClass". Vetia e klasës Objekti i klasës "MyClass" është fshirë.

Metodat dhe vetitë private

Karakteristikat dhe metodat e deklaruara private janë të aksesueshme vetëm brenda klasës në të cilën janë përcaktuar. Do të thotë se edhe nëse klasa e re rrjedh nga një klasë që përcakton vetitë dhe metodat private, ato nuk do të jenë të disponueshme në klasën e prejardhur.

Për demonstrim, le të deklarojmë metodën getProperty() si private V Klasa ime, dhe le të përpiqemi të thërrasim metodën callProtected() nga
MyOtherClass :

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksioni publik __toString() ( echo "Përdor metodën toString: "; ktheje $this->getProperty(); ) funksionin publik setProperty($newval) ( $this->prop1 = $newval; ) funksionin privat getProperty( ) ( ktheni $this->prop1 . "
"; ) ) klasa MyOtherClass zgjeron MyClass (funksioni publik __construct() ( prind::__construct(); echo "Ndërtues i ri në klasë " . __CLASS__ .".
"; ) funksioni publik newMethod() (echo "Nga një metodë e re e klasës" . __CLASS__ . ".
"; ) funksioni publik callProtected() ( return $this->getProperty(); ) ) // Krijo një objekt të ri $newobj = myOtherClass i ri; // Përdor metodën nga klasa prind echo $newobj->callProtected(); ?>

Ne ruajmë skriptin, rifreskojmë faqen në shfletues dhe marrim sa vijon:

Është krijuar një objekt i klasës "MyClass"! Konstruktor i ri në klasën "MyOtherClass". Gabim fatal: Thirrja në metodën private MyClass::getProperty() nga konteksti "MyOtherClass" në /Applications/XAMPP/xamppfiles/htdocs/testing/test.php në linjën 49

Metodat dhe vetitë statike (statike)

Metodat dhe vetitë e deklaruara me një direktivë statike mund të aksesohen pa inicimin e klasës. Ju thjesht përdorni emrin e klasës, operatorin e lejes së dukshmërisë dhe emrin e pronës ose metodës.

Një nga avantazhet kryesore të vetive statike është se ato ruajnë vlerat e tyre gjatë gjithë skenarit.

Për të demonstruar, le të shtojmë një veti statike $count dhe një metodë statike plusOne() në klasë Klasa ime. Më pas do të vendosim një cikli do...while për të printuar vlerën në rritje të $count derisa të jetë më e madhe se 10:

"; ) funksioni publik __destruct() (echo "Objekti i klasës"", __CLASS__, "" u fshi.
"; ) funksioni publik __toString() ( echo "Përdor metodën toString: "; ktheje $this->getProperty(); ) funksionin publik setProperty($newval) ( $this->prop1 = $newval; ) funksionin privat getProperty( ) ( ktheni $this->prop1 . "
"; ) funksion publik statik plusOne() ( return "count = " . ++self::$count . ".
"; ) ) klasa MyOtherClass zgjeron MyClass (funksioni publik __construct() ( prind::__construct(); echo "Ndërtues i ri në klasë " . __CLASS__ .".
"; ) funksioni publik newMethod() (echo "Nga një metodë e re e klasës" . __CLASS__ . ".
"; ) funksioni publik callProtected() ( kthe $this->getProperty(); ) ) bëj ( // Telefono plusOne pa inicuar klasën MyClass jehonë MyClass::plusOne(); ) ndërsa (MyClass::$count< 10); ?>

shënim- Për të pasur akses në vetitë statike, duhet që shenja e dollarit ($). vijnë pas operatorit të lejes së dukshmërisë.

Ekzekutimi i skriptit në shfletues do të prodhojë rezultatin e mëposhtëm:

Numëro = 1. numëro = 2. numëro = 3. numëro = 4. numëro = 5. numëro = 6. numëro = 7. numëro = 8. numëro = 9. numëro = 10.

informacion i pergjithshem

OOP është një stil programimi që u shfaq në vitet 80 të shekullit të 20-të. Ndryshe nga gjuhët procedurale, ku të dhënat dhe udhëzimet për përpunimin e tyre ekzistojnë veçmas, në programimin e orientuar nga objekti ky informacion kombinohet në një entitet të vetëm.

Parimet themelore të OOP

Trashëgimia

Parimi i dytë i OOP, trashëgimia, është aftësia e një klase për të përdorur metodat e një tjetri pa përsëritur zbatimin e tyre aktual. Trashëgimia ju lejon të heqni qafe tepricën në kodin burimor.

Polimorfizmi

Një tjetër parim i OOP është polimorfizmi. Përdorimi i tij do të thotë që për të manipuluar objekte me shkallë të ndryshme kompleksiteti, mund të krijoni një ndërfaqe që do të reagojë ndryshe ndaj ngjarjeve dhe në të njëjtën kohë do të zbatojë saktë detyrat e caktuara.

gjuhët OOP

Parimet OOP përdoren në gjuhët më të njohura të programimit si C++ dhe Java, në të cilat zhvillohen një pjesë e konsiderueshme e programeve dhe aplikacioneve. Ka edhe gjuhë OOP më pak të përdorura - Delphi, Object Pascal, Ruby dhe shumë të tjera.

Kritika ndaj OOP

Me gjithë deklaratat kryesisht pozitive ndaj kësaj metodologjie, parimet e OOP shpesh kritikohen. Ashtu si OOP, ai ka të metat e veta.

Së pari, vështirësia e tranzicionit. Do të duhet mjaft kohë për të kuptuar parimet e OOP, veçanërisht për njerëzit që punojnë ngushtë vetëm me gjuhët e programimit procedural.

Së dyti, disavantazhi është dokumentacioni më kompleks, pasi do të jetë e nevojshme jo vetëm të përshkruhen klasa dhe objekte, por edhe raste specifike të zbatimit të tyre.

Së treti, universaliteti i tepërt i metodave mund të çojë në faktin se kodi burimor dhe programet e zhvilluara do të mbingarkohen me funksione dhe aftësi që nuk janë të kërkuara në këtë rast të veçantë. Përveç kësaj, ata vërejnë joefikasitet në aspektin e shpërndarjes së kujtesës. Sidoqoftë, pavarësisht nga mendimet e të tjerëve, numri i programuesve OOP po rritet vazhdimisht, dhe vetë gjuhët po zhvillohen me shpejtësi.



Artikuj të ngjashëm: