» »

[PHP] oop in reference

[PHP] oop in reference

t3hn0 ::

Imam problem s prenosom referenc in kasnejšnjim nastavljanjem vrednosti. Če prilepim najprej kodo:

nadrazred
<?php
class Ref {
	
	protected $a, $t;
	
	public function __construct() {
		$this->a = "Ref nespremenjen";
		$this->t = new RefS();			// extendan razred
		$this->t->setA($a);				// ki mu podam neko spremenljivko
	}
	
	public function getA() {
		return $this->a;
	}
	
	// za uporabo v extendanem classu
	protected function setA(&$a) {
		$this->a = $a;   // ali "$this->a =& $a;", brez razlike
	}
	
	// za uporabo v extendanem classu
	public function changeA() {
		$this->t->addA(" z dodatkom");
	}
	
}

?>

podrazred
<?php
class RefS extends Ref {
	public function __construct() {}
	
	public function addA($add) {
		$this->a = $this->a . $add;
	}
	
}
?>

test
<?php
include_once "class.Ref.php";
include_once "class.RefS.php";

$t = new Ref();

echo $t->getA() . "<br />";

$t->changeA();

echo $t->getA() . "<br />";
?>

Zgornja koda izpise:
Ref nespremenjen
Ref nespremenjen

V čem je problem da se ne izpise "Ref nespremenjen z dodatkom"?
Torej da je neka spremenljivka iz nadrazreda prenešena podrazredu preko reference, v podrazredu pa bi nekaj dodal te spremenljivki.
^.^

MrBrdo ::

Sumim da zato, ker je $this->a verjetno bucket, ki si mu spremenil vrednost, namesto da bi spremenil vrednost referenci. Probaj za foro spremenit samo en znak, npr. $this->a[1] = 'x'; ce bo to delalo potem je to problem.
Pa ni mi najbolj vsec da v 9 vrstici uporabis $a namesto $this->a

Namrec, v 6 vrstici v RefS delas assignment. Poizkusi namesto = dati =&.
MrBrdo

Zgodovina sprememb…

  • spremenilo: MrBrdo ()

680x0 ::

Zato ker s klicem $t->changeA() v resnici ne spreminjaš private vrednosti $t->a, temveč $t->t->a.

var_dump($t)


object(Ref)#1 (2) {
  ["a"]=>
  string(16) "Ref nespremenjen"
  ["t"]=>
  object(RefS)#2 (2) {
    ["a"]=>
    string(11) " z dodatkom"
    ["t"]=>
    NULL
  }
}

Zgodovina sprememb…

  • spremenil: 680x0 ()

MrBrdo ::

Mislim da je to point, on hoce spremenit preko reference, da se spremeni na obeh mestih...
MrBrdo

t3hn0 ::

vmes sem raje šel na pivo :)

Hvala za odgovore, po spremembi v konstruktorju (Ref razred, 9 vrstica) iz $a v $this->a, je zadeva začela funkcionirati.

Zdej moram samo še ugotovitve popravit v dejanskem projektu :)

edit: Tako je MrBrdo!
Gre se za nek portal, kjer bo vsak plugin dodal svoje prevode k jeziku.
^.^

Zgodovina sprememb…

  • spremenil: t3hn0 ()

MrBrdo ::

Mimogrede, ni najlepsa praska, da v osnovnem razredu definiras metodo, ki klice metodo, ki jo definira podrazred. Ce ne drugega bi jo dodal tudi v osnovni razred in vrgel exception.
MrBrdo

t3hn0 ::

Misliš na changeA oz. addA? :)
Vem, sam sem mislil da bo tako prej jasno za kaj se gre. Kot sem napisal sem ta primer vrgel skupaj samo za sem gor, ker lepit projekt...hja, vsi vemo kako raste koda :)
^.^

MrBrdo ::

Jp. Pol pa kul, sam da ves :)
MrBrdo

Spura ::

MrBrdo je izjavil:

Mimogrede, ni najlepsa praska, da v osnovnem razredu definiras metodo, ki klice metodo, ki jo definira podrazred.

Zakaj pa ne? Jst to skos pocnem.

MrBrdo ::

Zato ker ni logično za ljudi ki izhajajo iz malo bolj striktnih jezikov, kjer je kaj takega tezko izvedljivo. In je potem po nepotrebnem lahko confusing.
MrBrdo

Mavrik ::

Zato pa majo striktni jeziki abstraktne metode, katerih namen je točno to. Še v C++ obstaja tak idiom.
The truth is rarely pure and never simple.

MrBrdo ::

Ne vem meni se to zdi grdo, maybe it's just me then. Jaz bi se temu ognil ce ni nujno potrebno.
Sicer pa je to nekaj drugega, ce imas abstraktno metodo ki jo ima ze base class. To je potem podobno, kot sem predlagal, da vrzes exception v base classu (kot implementacija te metode), ker pac compile time errorja nebos dobil v PHP, ker je to pac dovoljeno... Samo meni se zdi grdo.

Sej naceloma lahko ta konkreten primer isto nrdis v Cju (brez kaksnih abstract metod), ker itak instancira subclass. Sam to je tko, bizarno mal :) Meni ni vsec, da class v konstruktorju instancira svoj subclass, cela ideja v glavnem mi je faljena. Verjamem da deluje in da je cisto pravilno, samo pravim, da se mi ne zdi najboljsa praksa :)
MrBrdo

Zgodovina sprememb…

  • spremenilo: MrBrdo ()

Spura ::

Aja, da ne bo pomote, nisem mislil PHP varianto. Mislil sem pac kot abstraktna metoda, ki jo klice base class, podclassi jo pa implementirajo. Relativno pogost pattern IMO. Poznam pa ljudi, ki tega nikoli ne uporabljajo in jim je to cudno.

MrBrdo ::

Spura no saj to mi ni čudno, mi je pa čudno če base class sploh nima te metode, in potem še v konstruktorju instancira svoj podclass :)
MrBrdo

technolog ::

PHP ma tudi abstraktne metode.

MrBrdo ::

Ma bogve kaj vse ima PHP, verjetno ne bomo nikoli izvedeli, ko je pa 99% PHP programerjev mentalno se vedno na 3ki :D
MrBrdo


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

"Dinamicna" sprememba razreda v C++

Oddelek: Programiranje
131930 (1322) Spura
»

Java, pozicija kurzorja znotraj JPanel

Oddelek: Programiranje
7760 (638) marjan_h
»

[Java] Nejasna naloga

Oddelek: Programiranje
6994 (756) hexor
»

[C++] Dedovanje, virtualne in abstraktne metode

Oddelek: Programiranje
152978 (2777) mallard
»

[JAVA]Kako dostopati do privaten konstante podrazreda iz nadrazreda

Oddelek: Programiranje
71250 (1178) alexa-lol

Več podobnih tem