До сада смо радили програмирање које зовемо процедурално. Ипак, данас се многи програми у свету пишу тако да буду објектно-оријентисани. Веома је битно за програмера да познаје и процедурално и објектно-оријентисано програмирање, као и које су разлике између њих. Многи познати програмски језици попут Јаvе, С++, Python-а, често користе ООП (објектно-оријентисано) програмирање.
УВОД:
У уводу ћемо пробати да објаснимо неке кључне појмове ООП, који су неопходни за разумевање основа овог типа програмирања.
Идеја ООП је да програм има природну, интуитивну структуру.
Телевизор, улица, дрво, кућа, књига су само неки од објеката које срећемо у свакодневном животу. Идеја објектно oријентисаног програмирања је да се објекти из живота пренесу на програмирање. Зато је у програмирању објекат сваки елемент кога треба представити програму, подразумевајући под тим и „живе“ објекте, нпр. људе, животиње... Уопште ООП и његова идеја рада са објектима и догађајима из свакодневног живота, омогућава да програм буде написан на разумљивији и природнији начин. Тако имамо и могућност разбијања програма на мање целине, чиме обезбеђујемо лакше управљање.
ООП принципи су засновани на примени тзв. "црне кутије". Идеја црне кутије подразумева коришћење неког објекта, без конкретног знања о начину функционисања тог објекта. Као пример можемо навести телевизор. Свако од нас зна шта је и како да га користи, али се не замарамо тиме како он ради. Такође замена телевизора другим моделом подразумева неке ситне разлике између модела, али суштина и основна намена телевизора остаје иста, као и начин како га прикључујемо на електричну струју, где се прикључује антена итд.
Класе и креирање објеката
У програмирању, класа је шаблон на основу којег креирамо објекат. Класа се састоји из чланова класе. Чланови класе су сви елементи који сачињавају ту класу, у Python-у су то најчешће методе и атрибути. Методе су уствари функције, а атрибути су променљиве. Причајући о објектима, правили смо аналогију са телевизором, и рекли смо да знамо „како се користи“, али не знамо „како ради“. Најчешће нам методе обезбеђују „како се користи“ нешто, а целокупна класа са свим њеним члановима нам обезбеђује „како ради“.
class Imenik:
__kontakti[...]
def __dodavanje():
# logika za dodavanje kontakata
def __brisanje():
# logika za brisanje kontakata
def __pretrazivanje():
# logika za pretragu kontakata
На горњем примеру, који представља део кода неке класе, можете видети дефиницију класе Imenik. dodavanje, brisanje и pretrazivanje су методе класе. Коришћењем датих метода корисници могу да манипулишу са имеником, а променљива (атрибут) kontakti садржи потребне податке са којима се ради. Постоји појам који се зове модификатор приступа.Модификатори приступа служе да одреде који ће чланови класе бити видљиви остатку света, а који ће бити видљиви само у датој класи. Две доње црте ( __ ) уз поље kontakti означава да ће ово поље бити видљиво само у класи Imenik. Свака другачија синтакса од те означава да је тај појам (атрибут, метода, класа...) јаван, и да сви могу да га виде.
Класа је уствари шаблон на основу кога ћемо креирати објекат. Уобичајени назив за креирање објекта је инстанцирање.
mojImenik = Imenik()
mojImenik.dodavanje()
Објекат mojImenik смо креирали на основу класе Imenik. У следећем реду смо стартовали методу dodavanje, објекта mojImenik.
Методе и променљиве
Методе се састоје из потписа и тела методе. Оне су уствари исто што и функције у процедуралном програмирању. Под потписом подразумевамо повратни тип, назив методе и улазне параметре. Тело методе садржи саму функционалност методе, односно егзактни посао који она одрађује. Повратни тип је резултат који метода враћа. На горњем примеру ниједна метода не враћа никакву вредност. Улазни параметри су подаци које прослеђујемо методи, при њеном позивању, али метода не мора садржати ниједан улазни параметар што је и случај на горњем примеру.
Једна од објектно оријентисаних могућности коју има Python је такозвано преоптерећење метода (overload), односно ситуација да неколико метода назовемо истим именом, а да имају другачије потписе.
class Аritmetika:
def __sabiranje(self, a, b):
return a +b
def __sabiranje(self, a, b, c, d)
return a + b + c + d
Преоптерећење метода често користимо у ситуацији када требамо да извршимо исту операцију, сабирање у нашем случају, али број улазних параметара варира. Тако прва метода као улазне параметре узима две целобројне (int) вредности, а као резултат враћа целобројну вредност збира улазних вредности,а друга метода прима четири целобројне вредности као улазне параметре, а повратни тип је њихов збир.
Основни принципи објектно оријентисаног програмирања
Основни принципи објектно оријентисаног програмирању су:
- Апстракција
- Енкапсулација
- Модулараност
- Полиморфизам
- Наслеђивање
Енкапсулација и апстракција су појмови који се међусобно допуњују и тешко их је до краја раздвојити. Апстракција је процес запажања особина и понашања објеката, а енкапсулација се односи на то како ће се такво понашање испунити. Најпростије речено, на примеру нашег телевизора с почетка, апстракција би била гледање телевизора из угла гледаоца – односно "шта ради", а енкапсулација би била конкретна имплементација – "како ради". При томе енкапсулација подразумева скривање унутрашње структуре класе и приказивање корисницима само оног дела који треба да виде.
Један од основних аспеката ООП-а је наслеђивање. Нека суштинска дефиниција наслеђивања је да оно представља везу између класа у којој једна класа наслеђује структуру и понашање друге класе. Класа која се наслеђује назива се базном или основном класом, а класа која је наслеђује назива се изведеном класом. Дакле, наслеђивање је хијерархијска организација класа, где једна класа наслеђује другу и задржава комплетан садржај класе коју наслеђује и тај садржај може проширити или изменити.
У директној вези са наслеђивањем је и полиморфизам – вероватно једно од најмоћнијих особина објектно оријентисаног програмирања. То је особина да објекат извршава операцију на начин својствен изведеној класи којој припада, мада му се приступа као објекту основне класе.
Погледајмо следећи пример неког једноставног процедуралног програма
пример:
Сада ћемо исти тај програм представити у ООП концепту:
Хајде да анализирамо класу. Класа се зове"PromenaBroja" и има три методе:
__init__
dodajPet
pomnozi
Ове три методе имају сличан код и потпис.
def __init__(self):
def dodajPet(self,broj):
def pomnozi(self,cinilac):
Обратите пажњу како свака метода има параметар под називом "self ". Овај параметар мора бити у свакој методи класе. Он не мора да се зове "self", али то је нека стандардна пракса у Python-у. Овај параметар је неопходан у сваком методу, јер када се метода извршава, она мора да зна са чијим атрибутима ради. Дакле ако у методи напишемо self, значи да ће се односити на атрибуте класе у којој је та метода.
Сада ћемо анализирати прву методу:
def __init__(self):
Већина класа у Рython-у има __init__ методу која се извршава аутоматски чим се направи инстанца(објекат) класе. Ова метода се обично назива конструктор методе. У __init__ методи, поставили смо вредност атрибута broj на 0. Тачка се користи да се приступи атрибуту објекта.
У линији кода self.__broj = 0, self значи да је __broj атрибут класе у којој је ова метода.
def __init__(self):
self.__broj = 0
Хајде да видимо следећу методу:
def dodajPet(self,broj):
self.__broj = broj
return self.__broj + 5
Ова метода се зове "dodajPet ". Она прихвата параметар под називом "broj" из програма користећи класу. Метода затим поставља вредност тог параметра на атрибут "broj" унутар објекта. Метода враћа вредност "broj", на коју је додато 5, дакле враћа broj+5.
Анализа треће методе:
def pomnozi(self,cinilac):
self.__cinilac = cinilac
return self.__cinilac * 2.453
Ова метода је названа "pomnozi". Она прихвата параметар под називом "cinilac". Она додељује вредност параметра " cinilac" атрибуту, и враћа вредност " cinilac " атрибута помноженог 2.452