PHPPamokos.lt


14. Objektinis programavimas

Objektinis programavimas yra būdingas daugeliui programavimo kalbų. Iš esmės, tai yra programavimo "filosofija", siekiant tvarkingesnio, suprantamesnio ir korektiškesnio programinio kodo.

Programavimo pasaulyje vyrauja dvi didelės programavimo "filosofijos" - tai yra funkcinis programavimas (kai visi veiksmai yra suskirstyti į funkcijas) bei objektinis programavimas (kai tos funkcijos yra sugrupuotos į klases, taip pat klasės turi savo atributus ir kt). Visas PHP kodas, iki šiol jūsų matytas šio kurso rėmuose, buvo parašytas būtent funkcinio programavimo pagrindu, o dabar metas supažindinti jus su kiek kitokiu pasauliu.

Tiesa, reikia pabrėžti, kad šioje pamokoje bus tik įvadas į objektinį programavimą, nes tai daug daug platesnė tema. Bet kadangi ji labai svarbi - gera žinia jums: apie objektinį programavimą su PHP yra ruošiamas atskiras ilgas kursas, kur pasiaiškinsime visas reikalingas detales. O kol kas - papasakosiu esmę.

Kas yra OOP ir kam jo reikia

Objektinis programavimas (angl. Object-Oriented Programming) arba OOP reikalingas tada, kai norite tvarkos savo kode. Kai norite aiškiau suprasti, bei kad kiti suprastų projekto struktūrą. Ir kad funkcijos tarpusavyje "nesusipjautų".

Sakykime, kad jūs kuriate tinklalapį su nuorodomis į įdomius puslapius. Ten norite suskirstyti savo funkcijas į grupes pagal jų paskirtį. Vienos funkcijos yra susijusios su vartotojais, kitos - su nuorodų klasifikavimu, dar dalis funkcijų - su komentarais ir atsiliepimais.

Tokios funkcijų grupės yra grupuojamos į klases, kurios yra kuriamos su žodžiu class.

Taigi, suskirstykime aukščiau paminėtas funkcijas į tris atskiras klases. PHP kalboje tai atrodytų maždaug taip:

// pirmiausia - klasė darbui su vartotojų duomenimis,
// kurie saugomi duomenų bazėje
class Vartotojai {
  function SukurtiVartotoja($vardas, $slaptazodis, $el_pastas) {
    $query = "insert into vartotojai ...";
    // ... funkcija vartotojo sukūrimui
  }

  function VartotojoDuomenys($id) {
    $query = "select * from vartotojai where id = $id";
    // ... iš duomenų bazės paimami vartotojo duomenys
  }

  function PrisijungimoDuomenys($vardas, $slaptazodis) {
    $query = "select id from vartotojai
    where vardas = '".$vardas."'
    and slaptazodis = '".$slaptazodis."'";
    // ... patikriname, ar vartotojas įvedė
    // teisingus prisijungimo duomenis
  }
}

/* --------------------------------------- */

// antra klasė - naudingų nuorodų talpinimas ir grupavimas
class Nuorodos {
  function IterptiNuoroda($pavadinimas, $kategorija, $adresas) {
    $query = "insert into nuorodos ...";
    // ... įterpia nuorodos įrašą į duomenų bazę
  }

  function NuoroduKategorijos() {
    $query = "select * from nuorodu_kategorijos order by pavadinimas";
    // ... ištraukia iš duomenų bazes nuorodų kategorijas pagal abėcėlę
  }

  function IdomiausiosNuorodos() {
    $query = "select nuorodos.pavadinimas, count(*) as ivertinimai
      from nuorodu_ivertinimai
      join nuorodos on nuorodu_ivertinimai.nuorodos_id = nuorodos.id
      group by nuorodos.pavadinimas order by ivertinimai
      limit 0,10";
    // ... sudėtingesnė užklausa į duomenų bazę –
    // TOP 10 nuorodų pagal lankytojų įvertinimus
  }
}

/* --------------------------------------- */

// ir galiausiai - klasė, susijusi su komentarais
class Komentarai {
  function IterptiKomentara($nuoroda_id, $vartotojas_id, $komentaras) {
    $query = "insert into nuorodu_komentarai ...";
    // ... įterpia vartotojo komentarą prie nuorodos
  }

  function NaujausiKomentarai() {
    $query = "select * from nuorodu_komentarai order by id desc limit 0,10";
    // ... ištraukia iš duomenų bazės 10 naujausių komentarų
  }

  function NuorodosKomentarai($nuoroda_id) {
    $query = "select * from nuorodu_komentarai
      where nuoroda_id = $nuoroda_id
      order by id desc limit 0,10";
    // ... ištraukia iš duomenų bazės komentarus
    // prie konkrečios nuorodos
  }
}

Štai toks gana ilgas pavyzdys. Tikiuosi, iš jo pakankamai suprantama klasių struktūra. Kiekviena klasė turi apibrėžiama žodžiu class, tada nurodomas klasės pavadinimas ir vėliau tarp laužtinių skliaustų { } rašomas visas klasės tekstas.

Be funkcijų (arba, taip vadinamų, klasės metodų) klasė gali dar turėti ir savo vidinius kintamuosius arba klasės atributus. Jie aprašomi su specialiu žodeliu var:

// pavyzdys - klasė, skirta darbui su automobiliais
class Automobiliai {
  var $marke = 'audi';
  var $modelis;

  function Masina($marke, $modelis) {
    $this->marke = $marke;
    $this->modelis = $modelis;
    // ... kiti veiksmai
  }
}

Kaip matote, yra aprašyti du klasės atributai, ir vienam iš jų yra priskirta pirminė reikšmė (jos vėliau gali būti keičiamos).

Taip pat svarbu, kaip reikia kreiptis į tuos kintamuosius. Tam naudojamas žodelis $this bei simbolių junginys ->. Lygiai taip pat reikia kreiptis ir į klasės metodą, jeigu reikia jį iškviesti iš kito metodo:

// pavyzdys - klasė, skirta darbui su automobiliais
class Automobiliai {
  var $marke = 'audi';
  var $modelis;

  function Masina($marke, $modelis) {
    $this->marke = $marke;
    $this->modelis = $modelis;
    // ... kiti veiksmai
  }

  function NaujaMasina($marke, $modelis) {
    $this->Masina($marke, $modelis);
    // ... tolimesnis užklausos rezultatų apdorojimas
  }
}
 

Objektai ir klasių panaudojimas

Dabar apie tai, kaip sukurtas klases ir jų metodus panaudoti išorėje. Bendru atveju, jeigu mums reikia panaudoti kokią funkciją, mes tiesiog ją iškviečiame - parašome jos pavadinimą ir parametrus. Su klasėmis yra kiek kitaip: prieš tai reikia sukurti tos klasės objektą, o tada jau galima bus atlikti veiksmus su tuo objektu.

$db = new Automobiliai();

Išverčiant į žmogišką kalbą, mes kažkokiam kintamajam priskiriame norimos klasės apibrėžimą. Programavime tas kintamasis vadinamas klasės objektu. Vėliau būtent su tuo objektu mes atlikinėsime veiksmus. Įdomiausia tai, kad galima sukurti kelis tos pačios klasės objektus, ir su jais dirbti atskirai. Pavyzdys:

$masina1 = new Automobiliai();
$masina1->Masina('audi', 'a6');
// kitas tos pačios klasės objektas
$masina2 = new Automobiliai();
$masina2->Masina('toyota', 'auris');

Kaip matote, sukūrę objektą, mes galime ne tik iškviesti jo metodus, bet ir priskirti reikšmę jo atributams-kintamiesiems, kurie vėliau įtakoja metodų iškvietimo parametrus.

 

Paveldėjimas

Dar viena svarbi objektinio programavimo galimybė ir galimybė kurti klases, kurios paveldimos viena nuo kitos. Sakykime, jūs turite klasę Transportas, kurios pagalba dirbate su duomenimis apie transporto priemones. Tačiau vėliau matote, kad projektas išsipletė, ir jums reikia atskiro funkcionalumo krovininiams automobiliams, ir atskirų funkcijųmotociklams. Bet dalis iš tų funkcijų vis tiek turi būti bendros. Sprendimas atrodo taip:
// bendra klasė, skirta duomenims apie transportą
class Transportas {
  function RegistruotiTransporta() {
    // ... funkcija transporto priemones registravimui
  }
  // ... dar keletas funkcijų, skirtų bendrai transporto priemonėms
}

// klasė krovininiams automobiliams
class Krovininiai EXTENDS Transportas {
  var $krovinio_mase;
  function KrovinioMase() {
    // ... funkcija, skirta tik krovininiam transportui
  }
}

// klasė motociklams
class Motociklai EXTENDS Transportas {
  var $motociklu_klase;
  function MotocikloKlase() {
    // ... funkcija, skirta tik motociklams
  }
}

// klasių objektų sukūrimas
$krovininis = new Krovininiai();
$krovininis->KrovinioMase();
$krovininis->RegistruotiTransporta();
$motociklas = new Motociklai();
$motociklas->MotocikloKlase();
$motociklas->RegistruotiTransporta();

Specialiu žodeliu extends mes užrašome, kad kuriama klasė paveldima nuo kitos klasės ir tuo pačiu paveldi visas jos savybes bei objektus. Kaip matome žemiau, dviejų sukurtų paveldėtų klasių objektai prieina kaip prie savo individualių funkcijų, taip ir prie bendrų "tėvinės" klasės funkcijų.



(c) 2015-2018. Visais klausimais kreipkitės povilas@laraveldaily.com