Mé dotazy na OOP v PHP – PHP – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Mé dotazy na OOP v PHP – PHP – Fórum – Programujte.comMé dotazy na OOP v PHP – PHP – Fórum – Programujte.com

 

polonium0
Návštěvník
26. 11. 2009   #1
-
0
-

Zdravím,

Měl bych pár dotazů ohledně OOP. Pročítal jsem si seriál na portálu interval.cz ale některé věci mi přeci jen nejsou jasné a proto se obracím na vás a doufám, že mi pomůžete. Předem děkuji za pomoc.

http://php.interval.cz/objektove-orientovane-programovani-oop-v-php/

1) Proč mimo třídu vytvořím rozhraní (interface) a poté jej zahrnu (implements) do třídy, když v ní právě tyto dvě funkce jsou. Využítí objektového rozhraní mi přijde celkem nepoužitelné.



interface Rozhrani{
public function VypisuRozhrani();
public function VypisParametr($parametr);
}

class Trida implements Rozhrani{
public function VypisuRozhrani(){
echo 'Rozhraní bylo zahrnuto';
}

public function VypisParametr($parametr){
echo $parametr;
}
}

2) Jaký mají význam abstraktní objekty a metody?

Nahlásit jako SPAM
IP: 85.161.39.–
bukaj_0010
Věrný člen
26. 11. 2009   #2
-
0
-

polonium
Proč mimo třídu vytvořím rozhraní (interface) a poté jej zahrnu (implements) do třídy, když v ní právě tyto dvě funkce jsou. Využítí objektového rozhraní mi přijde celkem nepoužitelné.
interfaces význam mají, ale nesmíš o nich přemýšlet takto jednotlivě, nýbrž v kontextu celé aplikace. Použiju terminologii z trochu jiného jazyka – Objective-C –, protože mi přijde názornější. V ObjC se interfaces nazývají protokoly. Co je protokol víš, ne? Např. HTTP[1] je protokol pro přenášení HyperTextu a zároveň je to protokol, jímž přijde i tahle stránka do tvého počítače. Protokol specifikuje, co má která strana umět, aby spolu mohly komunikovat. Když si to převedeš do objektového světa, tak aby jeden objekt mohl komunikovat s druhým, musí vědět, jaké metody má ten druhý objekt dostupné.

Např. abys mohl komunikovat s databází, potřebuješ jí moci poslat nějaký dotaz:

interface Databaze {

function dotaz($sql);
}


Vytvoříš nějakou třídu, která interface implementuje:

class MySQLDatabaze implements Databaze {

function __construct($host, $uziv, $heslo, $db) {
$this->spojeni = mysql_connect($host, $uziv, $heslo);
mysql_select_db($db, $this->spojeni);
// ... atp.
}

function dotaz($sql) {
$vysledek = mysql_query($sql, $this->spojeni);
// ... zpracovaní výsledku dotazu
return $konecny_vysledek;
}
}



V kódu se pak odkazuješ pouze na tento interface (viz Type hinting[2]):

function vypisMenu(Databaze $db) {

$kategorie = $db->dotaz("select * from kategorie");
// ... zpracování výsledku dotazu
}


A když to zavoláš, PHP ověřuje, jestli předaný objekt implementuje rozhraní, které je vyžadováno:

$db = new MySQLDatabaze("localhost", "pepa", "heslo", "moje");

vypisMenu($db);

$nejaka_divnota = new stdClass;
vypisMenu($nejaka_divnota); // skončí chybou


Jednoduše řečeno jsou rozhraní způsobem, jak zajistit, že předávaný objekt bude rozumět tomu, co mu chceš říkat (jaké metody chceš volat).

Jaký mají význam abstraktní objekty a metody?
Abstraktní třídy stejně jako interfaces definují protokol, jímž se bude s objekty tohoto typu komunikovat. Ovšem implementace abstraktních metod je podmíněna tím, že objekty, které je implementují musí být potomkem (ať přímým, nebo nepřímým) dané abstraktní třídy.

PS. Mám v šuplíku jeden článek o OOP v PHP 5. Asi bych ho měl už konečně opravit a dát k konečné korektuře a vydání.

[1] http://en.wikipedia.org/wiki/Http
[2] http://php.net/manual/en/language.oop5.typehinting.php

Nahlásit jako SPAM
IP: 88.101.128.–
Jak se správně ptát? -> http://www.hash.cz/inferno/otazky.html[br][br] Po programování je člověk hladovej.
polonium0
Návštěvník
27. 11. 2009   #3
-
0
-

Jestli to dobře chápu tak v objektu Databaze vytvořím metodu dotaz($sql) a tu pak pomocí implements budu moct používat v jiném objektu budu moct s touto metodou pracovat.



class Databaze{
function dotaz($sql){
//... cokoliv
}
}

interface Databaze {
function dotaz($sql);
}

class Trida implements Databaze {
function vysledek(Databaze $db){
$this->V = mysql_fetch_array($db->dotaz);
}
}

Nahlásit jako SPAM
IP: 195.113.185.–
d.mostek0
Návštěvník
27. 11. 2009   #4
-
0
-

To polonium : '
Představ si to interface například u myši. Myš má rozhraní: Klikni, PosunVertikální, PosunHorizontální.
To musí mít každá myš, tudíž je to rohraní Myš. Takže ať připojím k PC jakoukoli myš, tak to PC ví, že u myši může volat tyto metody. Samotná myš může mít samozřejmě i metody typu Kolečko, pravýKlik atd atd. Ale tyto metody budou používat jen specifické aplikace, které vyžadujou aby tyto metody myš měla. V kódu je to kvůli tomu, aby jsi měl vždy jsitotu, že třída bude některé metody implementovat. Ta třída se může měnit ... růst, zmenšovat se měni kód, ale pořád máš jistotu, že bude mít ty metody určené v interface.

S tou myší by to mohlo vypadat takhle:



interface mouse{
function posunX(oKolik);
function posunY(Okolik);
function Klik();
}

class obycejnaMys implements mouse{
function posunX(oKolik){
$this->pointerX += oKolik;
}
function posunY(Okolik){
$this->pointerY += oKolik;
}
function Klik(){
$this->clicked= true;
}
}

class superMys implements mouse{
function posunX(oKolik){
$this->necojinyhoX += oKolik;
}
function posunY(Okolik){
$this->necojinyhoY += oKolik;
echo "Ahoj";
}
function Klik(){
$this->BSOD= true;
}

function kolecko(){
$this->kolecko.posun();
}
}

Nahlásit jako SPAM
IP: 147.32.127.–
www.dominik-mostek.cz
polonium0
Návštěvník
27. 11. 2009   #5
-
0
-

Jasný, chápu. Interface mi říká, že objekt bude muset mít minimálně ty metody, které implementuju.

3)



$int = new Trida;
$int2 = new Trida2;

Pokud budu mít inicializované tyto dvě třídy a budu chtít volat v instanci Trida2 metodu Volej() z instance Trida. Je to proveditelné jinak než, že budu muset použít buď dědičnost nebo instanci Trida volat uvnitř Trida2 ?

Nahlásit jako SPAM
IP: 85.132.159.–
d.mostek0
Návštěvník
29. 11. 2009   #6
-
0
-

To polonium : Ještě je to proveditelné pomocí statických metod, ale to záleží na konkrétním případu.
Každopádně bych ti toto nedoporučoval, protože tím ti vzniká vazba mezi Trida a Trida2. Takovéto vazby by jsi měl omezit na minimum.

Nahlásit jako SPAM
IP: 85.13.98.–
www.dominik-mostek.cz
polonium0
Návštěvník
2. 12. 2009   #7
-
0
-

To d.mostek :

Ještě je to proveditelné pomocí statických metod, ale to záleží na konkrétním případu.
Každopádně bych ti toto nedoporučoval, protože tím ti vzniká vazba mezi Trida a Trida2. Takovéto vazby by jsi měl omezit na minimum.


Mohl by jsi prosím rozvést svoji myšlenku ??

Nahlásit jako SPAM
IP: 85.161.192.–
d.mostek0
Návštěvník
2. 12. 2009   #8
-
0
-

To polonium : Pkud myslíš ty statické metody, tak je to asi takto:
class Trida{
.... neco
static function Volej(){
// dělej něco cool ;-)
}
}

Tak pak z jakékoliv jiné třídy můžeš zavolat Trida.Volej()
Ale pozor: Metoda Volej nebude mít přístup k členským proměnným, nýbrž zase jen ke statickým

Jestli ti šlo o ty vazby: Třídy by jsi měl navrhovat tak, aby byly pokud možno nezávislé, nebo závislé co nejméně na existenci jiných tříd. Když pak budeš chtít použít třídu Trida2 v jiném projektu, kde není zapotřebí mít třídu Trida, tak do toho projektu budeš muset zahrnout i třídu Trida, protože bez ní nemůže Třída2 fungovat.

Nahlásit jako SPAM
IP: 147.32.127.–
www.dominik-mostek.cz
hrach
~ Redaktor
+1
Boss
2. 12. 2009   #9
-
0
-

Statické metody by se měli volat pomocí dvojtečky! Trida::Volej()

Nahlásit jako SPAM
IP: 90.179.27.–
http://jan.skrasek.com@hrachcz – webdeveloper
polonium0
Návštěvník
3. 12. 2009   #10
-
0
-

To d.mostek :
Mno já přemýšlím o OOP v tom směru, že celý projekt bude vypadat jako jeden velký spletenec tříd a tento spletenec bude odstartován v souboru index.php jedním řádkem :)

new Main();

Možná by nebylo odvěci přehodnotit mé smýšlení o OOP.

Nahlásit jako SPAM
IP: 85.161.78.–
polonium0
Návštěvník
29. 12. 2009   #11
-
0
-

Ahojte,

chtěl bych se vratit k rozhraní. Dočetl jsem se v knížce Mistrovství v PHP 5 o rozhraní ArrayAccess. Píšou tam, že pokud použijeme volání handleru třídy jako volání pole automaticky se spustí metoda offsetGet().

$pole = new TridaNaPole();

print $pole["jmeno"];

Zajímalo by mě jestli právě takhle fungují rozhraní. Že by dokázali automaticky spoustět funkce definovane v interface nebo to umí jen toto předdefinované rozhraní ??

Nahlásit jako SPAM
IP: 85.132.159.–
polonium0
Návštěvník
12. 1. 2010   #12
-
0
-

Mohl by mi některý z vás osvětlit práci s vyjímkami ??

Pokud jsem to správně pochopil tak existuje třída Exception, která musí být rodičem všech tříd které použijeme v catch. A potek Exception je objekt, který může dělat vlastně cokoliv.

Takže řekněme, že ošetřím připojení k db:

class Database {

$this->spojeni = @mysql_connect("HOST", "NAME", "PASS");
if(!$this->spojeni)
throw new Vyjimka("Spojeni s databasi selhalo !");
}
A kdesi v kódu budu mít:
try {

$db = new Database;
}catch(Vyjimka $vyjimka){
print $vyjimka;
}

Nahlásit jako SPAM
IP: 85.161.53.–
polonium0
Návštěvník
12. 1. 2010   #13
-
0
-

- Předpokládám, že catch(Vyjimka $vyjimka) je vlastně hint, a že...
- throw musí vždy být objekt ??
- Při vzniku vyjímky se přeruší jen to co je v bloku try ??

Nahlásit jako SPAM
IP: 85.161.53.–
polonium0
Návštěvník
31. 3. 2010   #14
-
0
-

Je možné zapouzdřit třeba public $pole tak aby žádný z prvků pole nešel změnit pokud je již nadefinován ?? A pokud ano tak jak ??

Nahlásit jako SPAM
IP: 85.132.159.–
hrach
~ Redaktor
+1
Boss
31. 3. 2010   #15
-
0
-

To polonium :
- musi byt objekt a predekm musi byt Exception
- jo, je to hint
- pri vyhozeni vyjimky se prerusi vsechno, pokud je v try-catch bloku, tak se chytne catch blok
- ano, lze zapouzřdit, uděla $pole private a napsat si vlastni gettery a settery pomoci __set() a __get()

Nahlásit jako SPAM
IP: 88.101.68.–
http://jan.skrasek.com@hrachcz – webdeveloper
polonium0
Návštěvník
31. 3. 2010   #16
-
0
-

Mno otázkou stále zůstává jak. Měl by jsi v rukávu nějaký odkaz kde jsou pěkně methody __get() a __set() popsané ?? Ptže ja to nějako nepobírám...

Nahlásit jako SPAM
IP: 85.132.159.–
hrach
~ Redaktor
+1
Boss
31. 3. 2010   #17
-
0
-



public function __set($key, $value)
{
if ($key == 'pole') {
if (!empty($this->pole))
$this->pole = $value;
else
throw new Exception('Pole uz je naplneno');
}

# tady vyresit jak se to bude chovat, kdyz budes chtit napsat setter pro neco jinyho
}

public function &__get($key)
{
if ($key == 'pole') {
return $this->pole;
}
# tady opet vyresit chovani pro jine pretizeni...
}

Nahlásit jako SPAM
IP: 88.101.68.–
http://jan.skrasek.com@hrachcz – webdeveloper
polonium0
Návštěvník
1. 4. 2010   #18
-
0
-

mno zkoušel jsem ten __get() s i bez & a zjistil jsem, že pokud je bez & tak ingoruje změny, které provedu s proměnnou nebo polem mimo dannou třídu ale pokud tam & je tak ať jsem zkoušel __set() nastavit jak koliv tak mi to vždicky tu proměnnou nebo pole změnilo :(

Nahlásit jako SPAM
IP: 85.132.159.–
hrach
~ Redaktor
+1
Boss
1. 4. 2010   #19
-
0
-

asi to & tam byt nema; ale nechapu, co ti pak nefunguje.

Nahlásit jako SPAM
IP: 88.101.68.–
http://jan.skrasek.com@hrachcz – webdeveloper
polonium0
Návštěvník
2. 4. 2010   #20
-
0
-

mno pokud tam to & je tak můžu měnit ty pole, které chci pouze zviditelnit. Ale když to funguje bez __set() tak už bych to nepitval :) Díky za radu

Nahlásit jako SPAM
IP: 85.132.159.–
polonium0
Návštěvník
29. 6. 2010   #21
-
0
-

Zdravím,

mám třídu Database. V ní metodu query($query) a result().

$db->query("SELECT * FROM tabulka");

while($db->result()){
// zpracovani vysledku...
}


Z nějakého nepochopitelného důvodu mi $db->result() pokaždé vrací jen jeden řádek. Nechápu co je špatně.
// Náhled na methody Database

public function query($query){
$this->sql = mysql_query($query, $this->spojeni);
if(!$this->sql) return $this->log->zapisovac($query);
return $this->sql;
}

public function result(){
return mysql_fetch_array($this->sql);
}


Díky za odpověd :)

Nahlásit jako SPAM
IP: 85.132.159.–
KIIV
~ Moderátor
+43
God of flame
29. 6. 2010   #22
-
0
-

ja zase nechapu, o co se snazis... bud si ve while prirad ten radek do promenne
nebo nechapu jak z toho dokazes vubec jeden radek vydolovat..

mysql_fetch_array vrati jeden radek.. jako pole..

Nahlásit jako SPAM
IP: 94.142.234.–
Program vždy dělá to co naprogramujete, ne to co chcete...
polonium0
Návštěvník
30. 6. 2010   #23
-
0
-

Joo, jasně to byl překlep :D

$db->query("SELECT * FROM tabulka"); 

while($vyskedek = $db->result()){
// zpracovani vysledku...
}

Ovšem mě jde o to, že pokud předělám ty metody takto...
$dotaz = $db->query("SELECT * FROM tabulka"); 

while($vyskedek = $db->result($dotaz)){
// zpracovani vysledku...
}

Vše funguje jak má.

Nahlásit jako SPAM
IP: 85.132.159.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 2 hosté

Podobná vlákna

PHP OOP — založil Neony

PHP OOP začátečník — založil th

PHP a pochopení OOP — založil šnek

Sháníme PHP programátory (OOP) — založil K. Pěkná

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý