Upload
others
View
15
Download
8
Embed Size (px)
Citation preview
Osnove OOP PHP
Dr Nenad Kojić, dipl. inž.
Luka Lukić, struk. inž.
Školska 2017/18. Danijela Nikitin, spec .stuk.inž
Visoka škola strukovnih studija za informacione
i komunikacione tehnologije
OOP
▪Objektno orijentisano programiranje je način pisanja koda, koji odgovara uređenju poslova u realnom životu.
▪Kako se zaposleni u kompaniji organizuju po kancelarijama, koji se bave nekim specifičnim stručnim poslovima (računovodstvo, pravna služba, nabavka, marketing, magacija, pogon), tako se u OOP-u srodne aktivnosti grupišu u klase.
▪Na taj način se jasno zna ko je zadužen za koje aktivnosti i gde se taj kod očekuje u ukupnom kodu.
OOP
▪Tako se postiže načelo, da nema ponavljanja, i dobija se kompaktan kod, efikasan kod i lak za održavanje.
▪Ovakav način pisanja koda se često naziva i DRY (“don’t repeat yourself”) programiranje.
▪Najčešće se kod dobro napisanog koda ažuriranje realizuje samo na jednom mestu, umesto da se usaglašava promena na mnogo mesta kao u proceduralnom kodu.
Objekat vs Klasa
▪Termin objektno orijentisano programiranje baziran je nastrukturi podataka koje se naziva objekat.
▪ Međutim, termin objekat je nešto što dolazi nakondefinisanja Klase.
▪ Često se mešaju objekti i klase i to nerazumevanje praviveliki otpor u prihvatanju OOP koncepta.
▪Zato da to pojasnimo još jednom!
Klasa
▪U analogiji sa realnim životom, klasa je kao plan za izgradnjukuće.
▪Precizno je definisana dimenzija kuće, svake sobe, raspored, povezanost, pozicije vrata i prozora i sl. ali ta kućarealno ne postoji.
Objekat
▪Objekat je, sa druge strane, realno izgrađena kuća, u skladusa svim detaljima nacrta iz klase.
▪Ovakvih kuća može biti mnogo, i sve imaju zajedničkekarakteristike, jer su sve po istom planu pravljene.
Objekat
▪ Da li su kuće sa slike potpuno identične?
• Mogu da budu.
▪ Međutim, ako je neko ogradu napravio od drveta, a neko od metala, neko ima žutu kuću neko plavu, neko garnituru za sedenje na terasineko ne, nameštaj koji se razlikuje i sl. čine da ove kuće realno nisu iste.
▪ Ove nijanse u detaljima koje omogućuju razlikovanje objekata su podaciu objektu.
Kreiranje klasa
▪Očigledno je prvi korak kreiranje klase!
▪Kreiranje klase je pomoću rezervisane reči class
▪Primer kreiranje klase Osoba
<?php
class Osoba
{
// primer klase
}
?>
Kreiranje objekta
▪Kreiranje objekta klase se realizuje pomoću ključne reči new
▪Objekat klase se definiše proizvoljnim imenom promenljive
da bi kasnije znali kako ga oslovljavamo
$objekat = new ImeKlase;
▪Da bi se video sadržaj klase koristi se var_dump().
Primer
<?php
class Osoba
{
// primer klase
}
$objekat = new Osoba;
var_dump($objekat);
?>
Kreiranje klase Osoba
Kreiranje objekta klase Osoba
Svojstva klase
▪Rad sa svojstvima je kao i rad sa klasičnim promenljivima u
proceduralnom PHP-u.
▪ Razlika je što se može raditi samo sa onim svojstvima koja
su dodeljena objektu, i samo im se kroz njega može
pristupiti.
▪Pravila za imena svojstava su kao i pravila za imena
promenljivih
▪Preporuka je da se svojstvo definiše sa $ime-svojstva
Svojstva klase
<?php
class Osoba
{
// primer klase
public $ime = "Pera";
}
$objekat = new Osoba;
var_dump($objekat);
?>
Svojstvo klase
Pristup svojstvu
▪Obzirom da može da postoji više objekata koji su napravljeni
iz iste klase, a u svakom se može nalaziti svojstvo sa istim
imenom, bitno je naglasiti i kom tačno objektu i svojstvu se
radi.
▪U PHP-u se koristi -> da bi se definisalo kom objektu i kom
svojstvu se pristupa.
▪Obratiti pažnju da se nakon -> navodi samo naziv svojstva,
bez simbola $.
Pristup svojstvu
<?php
class Osoba
{
// primer klase
public $ime = "Pera";
}
$objekat = new Osoba;
echo $objekat->ime;
?>
Pristup svojstvu ime
Prava pristupa
▪Članovi klase mogu biti:
• Svojstva, tj. atributi
• Operacije (funkcije tj. metode)
▪Klasa i članovi klase mogu imati sledeća prava pristupa:
• public (dostupni su svima van klase, podrazumevani)
• protected (dostupni su funkcijama unutar klase i funkcijama u
klasama koje su izvedene iz posmatrane klase, ali ne i drugima koji su
van ovih struktura)
• private (dostupni samo funkcijama članicama klase)
Primer - private
<?php
class Osoba
{
// primer klase
private $ime = "Pera";
}
$objekat = new Osoba;
echo $objekat->ime;
?>
Pristup private svojstvu
izvan klase
Metode / funkcije
▪Metode su specifične funkcije neke klase
▪Specifične akcije koje će objekat moći da uradi se definišu u
klasi u njenim metodama.
▪Cilj metoda je da menjaju vrednosti atributa objekta i tako
menjaju stanje objekta
▪Kroz atribute objekta se definišu podaci koji će se u objektu
obrađivati.
Metode / funkcije
▪Operacije u klasama se najčešće definišu kao klasične
funkcije u PHP-u.
▪Kreiranje funkcije je pomoću rezervisane reči function.
▪Funkcija mora imati svoje ime, a može imati i jedan ili više
parametara.
▪Vrednosti izvršavanja funkcije mogu biti vraćene opcionom
naredbom return.
▪Ako se metoda eksplicitno ne pozove, njen rezultat rada se
ne vidi
Primer funkcije
<?php
class Osoba
{
// primer klase
public $ime = "Pera";
function pozdrav() {
echo "Zdravo. Ja sam Pera!";
}
}
$objekat = new Osoba;
$objekat->pozdrav();
?>
Kreiranje funkcije pozdrav()
koja ne vraća ništa, već
samo ispisuje tekst
upotrebom funkcije echo.
Pozivanje funkcije
pozdrav()
Primer funkcije sa parametrima
<?php
class Osoba
{
// primer klase
public $ime = "Pera";
function pozdrav($prezime) {
echo "Zdravo. Ja sam Pera ".$prezime."!";
}
}
$objekat = new Osoba;
$objekat->pozdrav("Peric");
?>
Funkcija koja prihvata
jedan parametar
Primer funkcije - return
<?php
class Osoba
{
// primer klase
public $ime = "Pera";
function pozdrav($prezime) {
return "Zdravo. Ja sam Pera ".$prezime."!";
}
}
$objekat = new Osoba;
echo $objekat->pozdrav("Peric");
?>
Kreiranje funkcije pozdrav()
koja vraća neku vrednost.
Kako funkcija vraća vrednost, dobijeni
rezultat treba ispisati sa echo
Funkcija sa opcionim parametrima▪Opcioni parameter se mora nalaziti na kraju liste argumenata i
imati podrazumevanu vrednost koja je najčešće null ili prazan
string.
<?php
class Osoba
{
// primer klase
public $ime = "Pera";
function pozdrav($ime, $prezime = null) {
echo "Zdravo. Ja sam Pera ".$prezime."! <br/>";
}
}
$objekat = new Osoba;
$objekat->pozdrav("Pera", "Peric");
$objekat->pozdrav("Pera");
$objekat->pozdrav(); // greska - $ime je obavezno
?>
Funkcija čiji je obavezan
prvi parametar, a drugi je
opcioni
$this
▪Kao i u većini drugih jezika, i PHP-u je promenljiva
$this rezervisana za ukazivanje na na tekući objekat
▪Pristup atributu tekućeg objekta je pomoću simbola ->
$this
<?php
class Osoba
{
// primer klase
public $ime = "Pera";
private $imePrezime;
function pozdrav($prezime){
$this->imePrezime = $this->ime . " " . $prezime;
return "Zdravo. Ja sam ". $this->imePrezime;
}
}
$objekat = new Osoba;
echo $objekat->pozdrav("Peric");
?>
Dodela vrednosti svojstvu
imePrezime tekućeg objekta
Dohvatanje vrednosti svojstva
imePrezime tekućeg objekta
Primer<?php
class Osoba
{
public $ime = "Pera";
private $zanimanje = "Student";
public function setZanimanje($zanimanje){
$this->zanimanje = $zanimanje;
}
public function getZanimanje(){
return $this->zanimanje;
}
}
$objekat = new Osoba;
echo $objekat->getZanimanje()."<br/>";
$objekat->setZanimanje("Programer");
echo $objekat->getZanimanje();
?>
Statičke promenljive i metode
▪Statičke promenljive se mogu inicijalizovati na tačno jednom
mestu u klasi i one su zajedno sa statičkim metodama
zajedničke za sve objekte neke klase.
▪Statičke metode se mogu pozivati iz objekta neke klase, ali
mogu se pozivati i samostalno tako što se pre metode
navede ime klase sa dve dvotacke.
Statičke promenljive i metode
▪Pozivanje statičkih svojstava i metoda unutar klase:
❖ self::svojstvo;
❖ self::metoda();
▪Pozivanje statičkih svojstava i metoda izvan klase:
❖ ImeKlase::svojstvo;
❖ ImeKlase::metoda();
Primer
<?php
class Krug
{
public static $pi = 3.14;
public static function vrati(){
return self::$pi;
}
public static function vrati1(){
return self::vrati();
}
}
echo Krug::$pi;
echo Krug::vrati();
?>
Konstruktori
▪Konstruktorom se pravi novi objekat
▪Sintaksno, konstruktor se definiše kao i druge funkcije, ali je
ime funkcije identično imenu klase
class Osoba
{
function Osoba($a)
{
echo(“Realizovan konstruktor sa parametrom $a!”);
}
}
Konstruktori
▪Konstruktori omogućavaju da se prilikom kreiranja objekta
istovremeno izvrši inicijalizacija svojstava u objektu
▪ Inicijalno PHP ne podržava preklapanje funkcija, pa moraju
imati jedinstvena imena
Instanca objekta sa konstruktorom<?php
class Osoba
{
public $ime;
public function Osoba($a) {
$this->ime = $a;
echo "Realizovan konstruktor sa parametrom $a!<br/>";
}
}
$objekat1 = new Osoba("Pera");
$objekat2 = new Osoba("Mika");
?>
▪ Kako se konstruktor poziva svaki put kada se pravi objekat, rezultat će
biti:
Pristupna funkcija
▪U slučaju da se podacima pristupa van klase, poželjno je
napisati pristupnu funkciju
<?php
class Osoba
{
public $ime = "Pera";
public function setIme($ime) {
$this->ime = $ime;
}
public function getIme() {
return $this->ime;
}
}
?>
Kopiranje i uništavanje objekta
▪ Kopiranje objekta se vrši sa rezervisanom reči clone
$objekat_copy = clone $prvi_objekat;
▪ Uništavanje objekta se vrši funkcijom unset()
unset($prvi_objekat);
$prvi_objekat->ispis(); //greska
Nasleđivanje
▪ Nasleđivanje klasa se definiše rezervisanom rečju extends.
▪ U klasi koja nasleđuje, dostupna su sva svojstva i metode iz natklase,
koje nisu private.
▪ Ukoliko je klasa Zaposleni nasledila klasu Osoba, tada se označava
kao:
class Zaposleni extends Osoba
{
public $plata;
function opis($vrednost) {
$this->plata = $vrednost;
echo this->plata;$
}
}
Primer – nasleđivanje<?php
class Osoba {
public $ime;
public function Osoba(){
echo "Osoba je kreirana <br/>";
}
}
class Zaposleni extends Osoba
{
public $plata;
function opis($ime, $vrednost){
$this->ime = $ime;
$this->plata = $vrednost;
echo $this->ime ." - ".$this->plata;
}
}
$zaposleni = new Zaposleni();
$zaposleni->opis("Pera", 5000);
?>
Svojstvo dostupno
iz natklase
Primer – nasleđivanjeclass proba
{
var $atribut1; // var = public
var $atribut2;
function obrada1($a)
{
$this->atribut1 = $a;
echo $this->atribut1."<br/>";
}
}
class proba_2 extends proba
{
var $atribut3;
var $atribut4;
function obrada2($b)
{
$this->atribut3 = $b;
echo $this->atribut3."<br/>";
}
}
$novi = new proba_2;
$novi->obrada1(111); // iz proba
$novi->atribut1 = 222; // iz proba
$novi->obrada2(333); // iz proba_2
$novi->atribut3 = 444; // iz proba_2
$novi = new proba;
$novi->obrada1(111);
$novi->atribut1 = 222;
$novi->obrada2(333);
$novi->atribut3 = 444;
Overriding metoda
▪ Često se kod izvođenja klasa nameće potreba da se promeni
način rada nekog metoda u baznoj klasi.
▪ Ako se u baznoj klasi Osoba definiše metod setIme i koji radi
neki posao, moguće se u klasi Zaposleni, koja je izvedena iz
klase Osoba, kreirati metod sa istim imenom kao u nadklasi, tj.
metod setIme koji radi potpuno drugi posao.
▪ Na ovaj način smo override-ovali metod setIme u klasi Osoba,
pravljenjem istog metoda u izvedenoj klasi.
Primer – override bazne klase
class Osoba {
protected $ime;
public function setIme($ime){
$this->ime = $ime;
}
public function getIme(){
return $this->ime;
}
}
class Zaposleni extends Osoba {
public function setIme($ime) {
$this->ime = strtoupper($ime);
}
}
Testiranje rezultata:
$zaposleni = new Zaposleni();
$zaposleni->setIme("Pera");
echo $zaposleni->getIme();
Overriding metoda
▪ U prethodnom primeru je override-ovan metod nadklase, tj.
bazne klase
▪ Isti proces može se uraditi i sa metodom u izvedenoj klasi
▪ U ovom primeru to bi značilo da se override-uje metod setIme u
klasi Zaposleni, koja je izvedena iz klase Osoba.
▪ Za ovo se koristi Osoba::setIme($ime);
▪ I tako se pristupa baznoj klasi Osoba tj. njenoj verziji metoda
setIme.
Primer – override izvedene klase
class Osoba {
protected $ime;
public function setIme($ime){
$this->ime = $ime;
}
public function getIme(){
return $this->ime;
}
}
class Zaposleni extends Osoba {
public function setIme($ime) {
Osoba::setIme($ime);
}
}
Testiranje rezultata:
$zaposleni = new Zaposleni();
$zaposleni->setIme("Pera");
echo $zaposleni->getIme();
Overriding metoda
▪ U prethodnom primeru korišćeni su :: za omogućavanje PHP kodu da
traži određeni metod van klase u kojoj se realizuje.
▪ Tako je oznaka Osoba::setIme() ukazala da se traži metod koji se zove
setIme() u klasi “Osoba”
▪ Pored ovog načina, postoji i kraći način pisanja kojim se postiže isti
efekat sa nadklasom.
▪ Ovo je omogućeno korišćenjem reči parent
parent::setIme($ime);
Primer – override izvedene klase
class Osoba {
protected $ime;
public function setIme($ime){
$this->ime = $ime;
}
public function getIme(){
return $this->ime;
}
}
class Zaposleni extends Osoba {
public function setIme($ime) {
parent::setIme($ime);
}
}
Testiranje rezultata:
$zaposleni = new Zaposleni();
$zaposleni->setIme("Pera");
echo $zaposleni->getIme();
Način pisanja koda
▪Do sada se kod koji pripada klasama kao i kod za kreiranje
objekata klase i dalji rad sa njima prikazivao unutar jedne PHP
strane
▪Praksa je da se ovi delovi koda pišu odvojeno, i da se klasa
piše u posebnom fajlu, koji se uključuje po potrebi u drugu PHP
stranu koja treba da koristi rad klasa.
▪Obično se fajl u kome se nalaze sve klase naziva biblioteka
klasa tj. skup klasa.
Primer – kod u jednom fajlu<?php
class Klasa_A{
public $podatak;
public function ispis() {
echo $this->podatak . "<br/>";
}
}
// Kreiranje objekta kao instance Klasa_A
$objekat = new Klasa_A();
// Definisanje vrednosti $podatak unutar klase
$objekat->podatak = "Ovo je prvi sadrzaj.";
// Kreiranje drugog objekta kao instance Klasa_A i definisanje druge vrednosti
$drugi_objekat = new Klasa_A();
$drugi_objekat->podatak = "Ovo je drugi sadrzaj.";
// Koriscenje metoda ispis klase Klasa_A
$objekat->ispis();
$drugi_objekat->ispis();
?>
Primer – kod u zasebnim fajlu
▪ Kod klase treba stavili u poseban php fajl koji možemo nazvati
class_lib.php i uključiti ga u stranicu index.php, u head sekciju,
pomoću
<?php include("class_lib.php"); ?>
class_lib.php
<?php
class Klasa_A{
public $podatak;
public function ispis(){
echo ($this->podatak . "<br/>");
}
}
?>
index.php<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" /><title>OOP PHP</title>
<?php include("class_lib.php"); ?>
</head><body>
<?php
// Kreiranje objekta kao instance Klasa_A
$objekat = new Klasa_A();
// Definisanje vrednosti $podatak unutar klase
$objekat->podatak = "Ovo je prvi sadrzaj.";
// Kreiranje drugog objekta kao instance Klasa_A i definisanje
druge vrednosti
$drugi_objekat = new Klasa_A();
$drugi_objekat->podatak = "Ovo je drugi sadrzaj.";
// Koriscenje metoda ispis klase Klasa_A
$objekat->ispis();
$drugi_objekat->ispis();
?> </body></html>
Poređenje objekata<?php
include "class_lib.php";
// Kreiranje objekta kao instance Klasa_A
$prvi_objekat = new Klasa_A();
// Definisanje vrednosti $podatak unutar klase
$prvi_objekat->podatak = "Ovo je prvi sadrzaj.";
// Kreiranje drugog objekta kao instance Klasa_A i definisanje druge vrednosti
$drugi_objekat = new Klasa_A();
$drugi_objekat->podatak = "Ovo je drugi sadrzaj.";
// Koriscenje metoda ispis klase Klasa_A
$prvi_objekat->ispis();
$drugi_objekat->ispis();
Poređenje objekata - nastavak// Poredjenje objekata sa ==
$poredjenje_objekata = ($prvi_objekat ==
$drugi_objekat);
if($poredjenje_objekata) {
echo("Provera 1 - Objekti su isti!");
}
else{
echo("Provera 1 - Objekti nisu isti!
<br/>");
}
// Promena vrednosti drugog objekta
$drugi_objekat->podatak = "Ovo je prvi
sadrzaj.";
$poredjenje_objekata = ($prvi_objekat ==
$drugi_objekat);
if($poredjenje_objekata) {
echo("Promena - Objekti su isti!<br/>");
}
else {
echo("Promena - Objekti nisu isti!");
}
// Poredjenje dva objekta sa === (po tipu,
referenci, vrednosti..)
$poredjenje_objekata = ($prvi_objekat ===
$drugi_objekat);
if($poredjenje_objekata) {
echo("Provera 2 - Objekti su isti!<br/>");
}
else {
echo("Provera 2 - Objekti nisu isti!");
}
?>
Magic Methodi
▪ PHP omogućava veliki broj “magičnih metoda” tj. posebno
kreiranih metoda koje se pozivaju kada se neka specifična
akcija desi sa objektom.
▪ Ovo omogućava programeru da se relativno lako obave vrlo
korisni poslovi.
▪ http://php.net/manual/en/language.oop5.magic.php
Magic Methodi
➢ __construct()
➢ __destruct()
➢ __clone()
➢ __toString()
➢ __get()
➢ __set()
➢ __isset()
➢ __unset()
Magic Methodi
➢ __sleep()
➢ __wakeup()
➢ __invoke()
➢ __call()
➢ __callStatic()
➢ __set_state()
➢ __debugInfo()
__construct()
▪ Kreiranje konstruktora kao funkcije sa imenom klase
function ImeKlase() { … }
predstavlja stariji način i od PHP verzije 5.3.3 se smatra regularnom
funkcijom.
▪ U PHP 7.0 ova sintaksa je “deprecated” i u budućnosti će biti
potpuno izbačena iz upotrebe.
▪ Nova notacija pisanja konstruktora klase, jeste korišćenje magic
metode
__construct()
__construct()
▪ Konstruktori roditelja, tj. natklase, se ne pozivaju implicitno
ukoliko izvedena klasa ima definisan konstruktor.
▪ Kako bi se pozvao konstruktor natklase, neophodno je u telu
konstruktora izvedene klase napisati
parent::__construct()
▪ Ako izvedena klasa nema definisan konstruktor, naslediće od
roditelja kao i sve metode (ukoliko nije privatan).
Primer - __construct()class Osoba {
protected $ime;
function __construct($ime){
$this->ime = $ime;
}
}
class Zaposleni extends Osoba {
protected $plata;
function __construct($ime, $plata){
parent::__construct($ime);
$this->plata = $plata;
}
public function ispis(){
return $this->ime.' - '.$this->plata;
}
}
$zaposleni = new Zaposleni("Pera", 5000);
echo $zaposleni->ispis();
__toString()
▪ Metod __toString() omogućava klasi da odluči kako će se
ponašati kada bude tretirana kao string.
▪ Na primer:
$objekat = new Zaposleni();
echo $objekat;
▪ Ovaj metod mora da vraća string, inače će se javi
E_RECOVERABLE_ERROR greška.
Primer - __toString()class Osoba {
protected $ime;
function __construct($ime){
$this->ime = $ime;
}
}
class Zaposleni extends Osoba {
protected $plata;
function __construct($ime, $plata){
parent::__construct($ime);
$this->plata = $plata;
}
public function __toString(){
return $this->ime.' - '.$this->plata;
}
}
$zaposleni = new Zaposleni("Pera", 5000);
echo $zaposleni;