Object-oriented programming

right|frame|Notasyon ng UML para sa isang *class*. Ang *Button class* na ito ay may mga baryabol para sa datos at mga *function*. Sa pamamagitan ng *inheritance*, maaaring lumikha ng isang *subclass* bilang isang subset ng *Button class*. Ang mga *object* ay mga *instance* ng isang *class*.
Ang ***object-oriented programming*** (OOP, literal: pagpoprogramang nakatuon sa bagay) ay isang paradigma (*paradigm*) sa pagpoprograma na nakabatay sa mga *object* (o bagay) – mga entidad ng software na naglalaman (*encapsulate*) ng datos at mga punsyon o *function*. Ang isang programang pang-kompyuter na OOP ay binubuo ng mga *object* na nakikipag-ugnayan sa isa't isa. Ang isang wikang OOP ay yaong nagbibigay ng mga katangian ng *object-oriented programming*, subalit dahil pinagtatalunan kung alin-alin ang mga katangiang bumubuo sa OOP, napagdedebatehan kung maituturing bang OOP ang isang wika – at kung hanggang saan nito sinusuportahan ang OOP. Dahil ang mga paradigma ay hindi magkakahiwalay o eksklusibo sa isa’t isa, maaaring maging maramihang-paradigma ang isang wika (ibig sabihin, maaari itong ikategorya sa higit pa sa OOP lamang).

Kabilang sa mga kilalang wikang pamprograma may suporta sa OOP ang Ada, ActionScript, C++, Common Lisp, C#, Dart, Eiffel, Fortran 2003, Haxe, Java, JavaScript, Kotlin, Logo, MATLAB, Objective-C, Object Pascal, Perl, PHP, Python, R, Raku, Ruby, Scala, SIMSCRIPT, Simula, Smalltalk, Swift, Vala, at Visual Basic (.NET).

## Kasaysayan 
Ang ideya ng mga "*object*" sa programming ay nagsimula sa pangkat ng artipisyal na intelihensiya sa *Massachusetts Institute of Technology* (MIT) noong huling bahagi ng dekada 1950 at unang bahagi ng dekada 1960. Dito, ang "*object*" ay tumutukoy sa mga *atom* ng LISP na may natukoy na mga katangian (*attributes*). Isa pang maagang halimbawa ang Sketchpad na nilikha ni Ivan Sutherland sa MIT noong 1960 hanggang 1961. Sa talahuluganan ng kaniyang teknikal na ulat, tinukoy ni Sutherland ang mga terminong gaya ng "*object*" at "*instance*" (na ang konsepto ng *class* ay saklaw ng "*master*" o "*definition*"), bagaman nakatuon ito sa interaksiyong grapikal. Pagkaraan, noong 1968, ang AED-0, bersiyon ng MIT ng wikang ALGOL, ay nag-ugnay ng mga estruktura ng datos ("*plexes*") at mga *procedure*, na nagpauna sa mga konseptong kalauna’y tinawag na "*messages*", "*methods*", at "*member functions*". Sa panahong ito, karaniwang paksa ng talakayan ang *data abstraction* (abstraksyon ng datos) at *modular programming* (pagpoprogramang modular).

Samantala, sa Norway, binuo ang Simula mula 1961 hanggang 1967. Pangunahing ginamit ang Simula ng mga mananaliksik na sangkot sa pisikal na pagmomodelo, tulad ng galaw ng mga barko at ng kanilang kargamento sa mga pantalan.

Naimpluwensiyahan ng MIT at ng Simula, sinimulan ni Alan Kay ang paglinang ng kaniyang sariling mga ideya noong Nobyembre 1966. Kalaunan, nilikha niya ang Smalltalk, isang makapangyarihang wikang OOP. Pagsapit ng 1967, ginagamit na ni Kay ang katawagang "*object-oriented programming*" sa mga pag-uusap. sinabi ni Kay na naiiba ang kaniyang mga ideya sa karaniwang pagkaunawa sa OOP, at ipinahiwatig niyang hindi tinanggap ng establisimyento ng agham pangkompyuter ang kaniyang pananaw.

Noong dekada 1970, binuo sa Xerox PARC ang unang bersiyon ng wikang Smalltalk nina Alan Kay, Dan Ingalls, at Adele Goldberg. Namukod-tangi ang Smalltalk-72 dahil sa paggamit ng mga *object* sa antas ng wika at sa grapikal na *environment* sa pag-*develop*. Ganap na dinamiko ang Smalltalk, na nagpapahintulot sa mga gumagamit na lumikha at magbago ng mga *class* habang sila’y gumagawa. Malaking bahagi ng teorya ng OOP ang na-*develop* sa konteksto ng Smalltalk, tulad ng *multiple inheritance*.

Noong huling bahagi ng dekada 1970 at dekada 1980, lalo pang sumikat ang OOP. Nilikha ang Flavors, isang *object-oriented* na Lisp, simula 1979, na nagpakilala ng *multiple inheritance* at *mixins*. Noong Agosto 1981, itinampok ng Byte Magazine ang Smalltalk at OOP, na nagpakilala ng mga ideyang ito sa mas malawak na madla. Ang LOOPS, ang *object system* para sa Interlisp-D, ay naimpluwensiyahan ng Smalltalk at Flavors, at nailathala ang isang papel tungkol dito noong 1982. Noong 1986, dinaluhan ng 1,000 katao ang unang Kumperensiya sa *Object-Oriented Programming, Systems, Languages, and Applications* (OOPSLA). Minarkahan ng kumperensiyang ito ang simula ng mga pagsisikap na pagsamahin ang mga *object system* ng Lisp, na kalauna'y humantong sa Common Lisp Object System. Noong dekada 1980, may ilang tangkang magdisenyo ng mga *processor architecture* na may suporta sa *hardware* para sa mga *object* sa memorya, subalit hindi nagtagumpay ang mga ito. Kabilang sa mga halimbawa ang Intel iAPX 432 at ang Linn Smart Rekursiv.

Noong kalagitnaan ng dekada 1980, lumitaw ang mga bagong wikang *object-oriented* tulad ng Objective-C, C++, at Eiffel. Binuo ang Objective-C ni Brad Cox, na gumamit ng Smalltalk sa ITT Inc. Nilikha ni Bjarne Stroustrup ang C++ batay sa kaniyang karanasan sa paggamit ng Simula para sa kaniyang tesis sa doktorado. at C++. Lalong sumikat ang OOP kasabay ng pag-usbong ng mga *graphical user interface*, na gumagamit ng mga *object* para sa mga pindutan, menu, at iba pang elemento. Isang kilalang halimbawa ang *framework* na Cocoa ng Apple, na ginagamit sa macOS at nakasulat sa Objective-C.

Sa ETH Zürich, lumikha si Niklaus Wirth at ang kaniyang mga kasamahan ng mga bagong lapit sa OOP. Ang Modula-2 (1978) at Oberon (1987) ay nagtatampok ng natatanging pagtingin sa *object orientation*, mga *class*, at *type checking* sa kabila ng mga hangganan ng mga *module*. Hindi lantad ang *inheritance* sa disenyo ni Wirth dahil kabaligtaran ang direksiyon ng kaniyang terminolohiya: tinatawag itong *type extension*, at ang pananaw ay mula sa magulang (o *parent*) pababa sa nagmamana.

Maraming wikang pamprograma na unang na-*develop* bago pa sumikat ang OOP ang kalauna'y dinagdagan ng mga katangiang *object-oriented*, kabilang ang Ada, BASIC, Fortran, Pascal, at COBOL.

## Mga katangian 
Nagkakaiba-iba ang mga katangiang OOP na ibinibigay ng bawat wika. Nasa ibaba ang ilang karaniwang katangian ng mga wikang OOP. Mahirap ihambing ang OOP sa iba pang estilo, gaya ng *relational programming* (pagpoprogramang relasyonal), dahil walang malinaw at pinagkaisahang depinisyon ng OOP.

### *Encapsulation* at *information hiding* 
Ang *information hiding* (pagtatago ng impormasyon) at *encapsulation* (enkapsulasyon) ay maaaring tumukoy sa ilang magkakaugnay na konsepto:

* '''*Cohesion* (pagkakaugnay)'*, ang pagsasama-sama ng magkakaugnay na mga *field* at *method*. Ang *field* (kilala rin bilang *attribute* o *property*) ay naglalaman ng impormasyon (tinatawag ding *state*) bilang isang *variable*. Ang *method* (kilala rin bilang *function* o *action*) ay naglalarawan ng asal (*behavior*) sa pamamagitan ng lohikal na *code* (kodigo).
* *'*Decoupling* (pagkakahiwalay ng mga bahagi)'*, ang pag-oorganisa ng *code* upang ang piling bahagi lamang ng datos ang ginagamit ng mga kaugnay na *function*. Pinapadali ng decoupling ang pagbabago sa panloob na paggana ng isang *object* nang hindi naaapektuhan ang ibang bahagi ng *codebase*, gaya sa *code refactoring* (o muling pagsasaayos ng kodigo). Ang mga *object* ay nagsisilbing hangganan sa pagitan ng kanilang panloob na mekanismo at ng panlabas na *code* na gumagamit sa kanila.
* *'*Data hiding* (pagtatago ng datos)'*, ang pagtatago ng mga panloob na detalye ng isang object mula sa panlabas na *code*. Ang *code* na gumagamit ay maaari lamang makipag-ugnayan sa *object* sa pamamagitan ng mga *public member*, dahil nagbibigay ang wika ng mga *access modifier* na kumokontrol kung paano nakikita (*visibility*) ang isang *variable*, *method* o *class* ng isang programa.

Ang ilang wikang pamprograma, gaya ng Java, ay nagbibigay ng *information hiding* sa pamamagitan ng mga *visibility keyword* tulad ng  at . Ang ibang wika, gaya ng Python, ay walang pormal na *visibility feature*, subalit sinusunod ng mga *developer* (o tagagawa ng programa) ang isang kumbensiyon tulad ng pagsisimula ng pangalan ng *private member* sa salungguhitan. Mayroon ding mga antas ng akses na nasa pagitan, gaya ng *keyword* na  ng Java (na nagpapahintulot ng akses mula sa parehong *class* at mga *subclass* nito, subalit hindi mula sa mga *object* ng ibang *class*), at ang *keyword* na  sa C#, Swift, at Kotlin, na naglilimita ng akses sa mga *file* sa loob ng iisang *module*.

Sinasabi ng mga tagasuporta ng *information hiding* at *data abstraction* (abstraksyon ng dataos) na pinapadali nito ang muling paggamit ng *code* at intuitibong kumakatawan sa mga sitwasyon sa tunay na mundo. Gayunman, may mga tumututol at nagsasabing hindi pinahuhusay ng OOP ang madaling pagbasa (*readability*) o modularidad. Isinulat ni Eric S. Raymond na ang mga wikang OOP ay may tendensiyang maghikayat ng makakapal na patong-patong na mga programa na sumisira sa kalinawas. Inihahambing niya ito nang hindi pabor sa lapit ng Unix at ng wikang C.

Kasama sa *SOLID* ang prinsipyong buk*as*/nakasara (*open/closed principle*), na nagsasaad na ang mga *class* at *function* ay dapat na "bukas para sa ekstensyon, subalit sarado para sa pagbabago". Ipinahayag ni Luca Cardelli na ang mga wikang OOP ay may "napakahinang katangian ng modularidad pagdating sa pagpapalawig at pagbabago ng *class*", at may tendensiyang maging labis na komplikado. na sumasalungat sa patakarang *don't repeat yourself* (huwag mong ulitin ang sarili mo) sa pagde-*develop* ng software.

### *Inheritance* 
Maaaring suportahan ang *inheritance* o pagmamana sa pamamagitan ng *class* o *prototype*. Magkaiba man ang mga ito, gumagamit sila ng magkakatulad na termino tulad ng *object* at *instance*.

#### Batay sa *class* 
Sa *class-based programming* (o pagpoprograma batay sa *class*), ang pinakakaraniwang uri ng OOP, ang isang *object* ay isang *instance* ng isang *class*. Tinutukoy ng *class* ang datos (mga *variable*) at mga *method* (lohika). Nililikha ang *object* sa pamamagitan ng *constructor*. Ang bawat *instance* ng *class* ay may parehong hanay ng mga *variable* at *method*. Maaaring kabilang ang mga elemento sa:

* *Class variable* – pag-aari ng mismong *class*; iisang kopya lamang ang pinagsasaluhan ng lahat ng *object* ng *class*
* *Instance variable* – pag-aari ng *object*; bawat *object* ay may sariling bersyon ng mga *variable* na ito
* *Member variable* – tumutukoy kapwa sa *class variable* at *instance variable* ng isang *class*
* *Class method* – maaari lamang gumamit ng *class variable*
* *Instance method* – pag-aari ng *object*; maaaring gumamit ng parehong *instance* at *class variable*

Maaaring magmana ang mga class mula sa iba pang class, na lumilikha ng isang herarkiya ng mga class: isang kaso ng *subclass* na nagmamana mula sa *super-class*. Halimbawa, ang *class* na  ay maaaring magmana mula sa *class* na , na nagbibigay sa *object* na  *Empleyado* ng mga *variable* mula sa *Persona*. Maaaring magdagdag ang *subclass* ng mga *variable* at *method* na hindi nakaaapekto sa *super-class*. Pinahihintulutan din ng karamihan sa mga wika ang *subclass* na i-*override* ang mga *method* ng *super-class*. Sinusuportahan ng ilang wika ang maramihang *inheritance*, kung saan ang isang *class* ay maaaring magmana mula sa higit sa isang *class*, at may iba namang sumusuporta sa mga *mixin* o *trait*. Halimbawa, ang isang *mixin* na tinatawag na *UnicodeConversionMixin* ay maaaring magdagdag ng *method* na *unicode_tungong_ascii()* sa parehong *class* na *FileReader* at *WebPageScraper*.

Ang isang *abstract class* ay hindi maaaring direktang gawing *object*. Ginagamit lamang ito bilang *super-class*.

Mayroon ding mga *utility class* na naglalaman lamang ng mga *class variable* at *class method*, at hindi nilalayong gawing *instance* o gawing basehan ng *subclass*.

#### Batay sa *prototype* 
Sa halip na magbigay ng konsepto ng class, sa *prototype-based programming* (o pagpoprograma batay sa *prototype*), ang isang *object* ay iniuugnay sa isa pang *object* na tinatawag na *prototype* o *parent*. Sa Self, maaaring magkaroon ang isang *object* ng marami o walang *parent*, subalit sa pinakapopular na wikang nakabatay sa *prototype*, ang JavaScript, ang isang *object* ay may eksaktong isang *prototype link*, hanggang sa batayang *object* na ang prototype ay *null*.

Ang prototype ay nagsisilbing modelo para sa mga bagong *object*. Halimbawa, kung mayroon kang *object* na , maaari kang lumikha ng dalawang *object* na  at  na nagbabahagi ng mga katangian ng *prototype* na . Pinahihintulutan din ng mga wikang nakabatay sa *prototype* ang mga *object* na magkaroon ng kani-kanilang natatanging katangian, kaya maaaring magkaroon ang *object* na  ng *attribute* na , samantalang wala nito ang *object* na  o . 

#### Walang *inheritance* 
Sa lahat ng wikang OOP, sa pamamagitan ng *object composition*, maaaring maglaman ang isang *object* ng iba pang mga *object*. Halimbawa, ang *object* na  ay maaaring maglaman ng *object* na , kasama ng iba pang impormasyon tulad ng  at . Ang *composition* ay isang ugnayang "mayroon" (*has-a*), tulad ng "ang empleyado ay may tirahan". Ang ilang wika, gaya ng Go, ay hindi sumusuporta sa *inheritance*. Sa halip, hinihikayat nila ang prinsipyong "*composition over inheritance*" (komposisyon kaysa pagmamana), kung saan binubuo ang mga *object* gamit ang mas maliliit na bahagi sa halip na ugnayang *parent* at *child*. Halimbawa, sa halip na magmana mula sa *class* na *Persona*, maaaring maglaman na lamang ang *class* na *Empleyado* ng isang *object* na *Persona*. Pinahihintulutan nito ang *class* *na Empleyado* na kontrolin kung gaano karami sa *Persona* ang ilalantad nito sa ibang bahagi ng programa. Ang *delegation* ay isa pang katangian ng wika na maaaring gamitin bilang alternatibo sa *inheritance*.

Magkakaiba ang pananaw ng mga *programmer* o tagapagprograma tungkol sa *inheritance*. Ipinahayag ni Bjarne Stroustrup, may-akda ng C++, na posibleng gumawa ng OOP nang walang *inheritance*. Pinuna naman ni Rob Pike ang *inheritance* dahil lumilikha ito ng masalimuot na herarkiya sa halip na mas payak na mga solusyon.

#### *Inheritance* at *behavioral subtyping* 
Madalas isipin na kapag ang isang *class* ay nagmana mula sa isa pa, nangangahulugan itong ang *subclass* ay "isang mas tiyak na uri" ng orihinal na *class*. Ipinapalagay nito na sa semantika ng programa, ang mga *object* mula sa *subclass* ay maaaring palaging ipalit sa mga *object* ng orihinal na *class* nang walang problema. Ang konseptong ito ay kilala bilang *behavioral subtyping* (o pagsa-subtipo ng pagkilos), partikular ang prinsipyong substitusyong Liskov.

Gayunman, madalas itong hindi totoo, lalo na sa mga wikang pamprograma na nagpapahintulot ng mga *mutable object*, mga *object* na nagbabago matapos malikha. Sa katunayan, ang *subtype polymorphism* na ipinapatupad ng *type checker* sa mga wikang OOP ay hindi makagagarantiya ng *behavioral subtyping* sa karamihan, kung hindi man sa lahat, ng konteksto. Halimbawa, ang *circle-ellipse problem* (o suliraning bilog-elipse) ay kilalang mahirap lutasin gamit ang konsepto ng *inheritance* sa OOP. Ang *behavioral subtyping* ay di-matukoy sa pangkalahatan, kaya hindi ito madaling ipatupad ng isang *compiler*. Dahil dito, kailangang maingat na idisenyo ng mga *programmer* ang mga herarkiya ng *class* upang maiwasan ang mga pagkakamaling hindi kayang hulihin ng mismong wika.

### *Dynamic dispatch* 
Maaaring tawagin ang isang method sa pamamagitan ng *dynamic dispatch* (o pagtatalagang dinamiko), kung saan pinipili ang *method* sa *runtime* (o oras ng pagtakbo) sa halip na sa oras ng pag-*compile*. Kapag ang pagpili ng *method* ay nakabatay sa higit sa isang uri ng *object* (tulad ng ibang mga *object* na ipinapasa bilang mga *parameter*), ito ay tinatawag na *multiple dispatch* (o maramihang pagtatalaga). Sa kontekstong ito, ang pagtawag sa *method* ay tinatawag ding *message passing* (o pagpapasa ng mensahe), na nangangahulugang ang pangalan ng *method* at ang mga *input* o ipinasok nito ay parang isang mensaheng ipinapadala sa *object* upang ito ay kumilos.

Gumagana ang *dynamic dispatch* kasabay ng *inheritance*: kung ang isang *object* ay walang hinihinging *method*, hahanapin nito ito sa *parent class* (*delegation*), at magpapatuloy pataas sa kadena hanggang sa makahanap ng tumutugmang *method*.

### *Polymorphism* 
Ang *polymorphism* (polimorpismo) sa OOP ay tumutukoy sa *subtyping* o *subtype polymorphism*, kung saan ang isang *function* ay maaaring gumana gamit ang isang tiyak na *interface'' at sa gayon ay manipulahin ang mga entidad ng iba't ibang *class* sa iisang paraan.

Halimbawa, isipin ang isang programa na may dalawang hugis: bilog at parisukat. Pareho silang nagmula sa isang karaniwang *class* na tinatawag na *Hugis*. Bawat hugis ay may sariling paraan ng pagguhit ng sarili nito. Sa *subtype polymorphism*, hindi na kailangang malaman ng programa ang eksaktong uri ng bawat hugis, at maaari na lamang nitong tawagin ang *method* na *Guhit* para sa bawat isa. Sisiguruhin ng *runtime* ng wika na ang tamang bersyon ng *method* *na Guhit*  ang tatakbo para sa bawat hugis. Dahil ang mga detalye ng bawat hugis ay pinangangasiwaan sa loob ng kani-kanilang *class*, nagiging mas simple at mas organisado ang *code*, at napapalakas ang malinaw na paghihiwalay ng mga tungkulin (*separation of concerns*).

### *Open recursion* 
Maaaring ma-*access* o tawagin ng mga *method* ng isang *object* ang datos ng mismong *object*. Maraming wikang pamprograma ang gumagamit ng isang espesyal na salita, tulad ng  o , upang tukuyin ang kasalukuyang *object*. Sa mga wikang sumusuporta sa *open recursion* (rekursyong bukas), ang isang *method* sa loob ng isang *object* ay maaaring tumawag ng iba pang mga *method* sa parehong *object*, kabilang ang sarili nito, gamit ang espesyal na salitang ito. Pinahihintulutan nito ang isang *method* sa isang class na tumawag ng isa pang *method* na tinukoy sa kalaunang *subclass*, isang katangiang kilala bilang *late binding* (huling pagtatalaga).

## Kasikatan at pagtanggap 
Maraming tanyag na wikang pamprograma, gaya ng C++, Java, at Python, ang gumagamit ng OOP. Noong nakaraan, malawak na tinanggap ang OOP, subalit sa mga nakaraang taon, may ilang *programmer* o tapagprograma na pumuna rito at mas pinipili na ngayon ang *functional programming* o pagpoprogramang punsyunal. Natuklasan sa isang pag-aaral nina Potok at iba pa na walang malaking pagkakaiba sa produktibidad sa pagitan ng OOP at *procedural programming* (pagpoprogramang pamamaraan).

Naniniwala ang ilan na labis na binibigyang-diin ng OOP ang paggamit ng mga *object* kaysa sa mga algoritmo at estruktura ng datos. Halimbawa, binigyang-diin ng *programmer* na si Rob Pike na maaaring magdulot ang OOP ng labis na pagtuon ng mga *programmer* sa herarkiya ng mga uri (*type hierarchy*) sa halip na sa komposisyon. Tinawag pa niya ang OOP na "mga numerong Romano ng kompyuting". Inilarawan naman ni Rich Hickey, lumikha ng Clojure, ang OOP bilang labis na pinasimple, lalo na pagdating sa paglalarawan ng mga bagay sa tunay na mundo na nagbabago sa paglipas ng panahon. Gayunman, hindi ito dinisenyo upang malinaw na ipakita ang daloy ng mga tagubilin ng isang programa. Ipinagkatiwala ito sa *compiler*. Habang nagsimulang gumamit ang mga kompyuter ng mas maraming *parallel processing* o  sabay-sabay na pagproseso at *multiple threads* (o maramihang tagabulin), naging mas mahalaga ang pag-unawa at pagkontrol sa daloy ng mga tagubilin. Mahirap itong gawin gamit ang OOP.

Naniniwala si Paul Graham, isang kilalang siyentista sa agham pangkompyuter, na gusto ng malalaking kumpanya ang OOP dahil nakatutulong ito sa pamamahala ng malalaking pangkat ng mga karaniwang *programmer*. Ayon sa kaniya, nagdaragdag ang OOP ng istruktura, kaya mas mahirap para sa isang tao na gumawa ng seryosong pagkakamali, subalit kasabay nito'y nililimitahan nito ang mga mahuhusay na *programmer*. Ipinapahayag naman ni Eric S. Raymond, isang *programmer* ng Unix at tagapagtaguyod ng *open-source software* (software na may bukas na *code*), na hindi ang OOP ang pinakamahusay na paraan ng pagsulat ng mga programa. Iginiit ni Lawrence Krubner na hindi nagbibigay ang OOP ng natatanging bentahe kumpara sa iba pang mga estilo, tulad ng *functional programming*, at maaari pa nitong gawing mas komplikado ang pagsulat ng *code*. Sinabi naman ni Luca Cardelli na mas mabagal ang OOP at mas matagal i-*compile* kaysa sa *procedural programming*.

## Mga sanggunian 
## Talababa 
*
* 

## Mga panlabas na link 
* Panimula sa Object Oriented Programming Concepts (OOP) at Higit pa  ni LWC Nirosh
* Pagtalakay sa Kahinaan ng OOP
* Mga Konsepto ng OOP (Mga Tutorial sa Java)

Kategorya:Mga paradigma sa pagpoprograma