2011-08-13 13:54:10

Łańcuch wywołań

Często w kodzie programów pisanych obiektowo można napotkać konstrukcje typu:

$obiekt = new Klasa($a);
$obiekt->metoda1($a)->metoda2($b)->metoda3(c);

Jednak gdy napiszemy prostą klasę i spróbujemy wywołać jej metody w ten sposób, otrzymamy błąd. Można o tym się przekonać na poniższym przykładzie.

<?php
	class Kalkulator
	{
		private $a=null;
 
		public function __construct($n)
		{
			$this->a=$n;
		}
 
		public function dodaj($n)
		{
			$this->a+=$n;
		}
 
		public function odejmij($n)
		{
			$this->a-=$n;
		}
 
		public function pomnoz($n)
		{
			$this->a*=$n;
		}
 
		public function podziel($n)
		{
			$this->a/=$n;
		}
 
		public function wynik()
		{
			return $this->a;
		}
	}
 
	$t=new Kalkulator(12);
	echo $t->dodaj(8)->podziel(5)->odejmij(1)->pomnoz(3)->dodaj(2)->wynik();
?>

wygenerowany błąd to:

Fatal error: Call to a member function podziel() on a non-object in C:\xampp\htdocs\index.php on line 38

Błąd mówi o tym, że metoda podziel jest wywoływana na czymś, co nie jest obiektem. Metoda podziel jest wywoływana jako druga w łańcuchu wywołań. Z tego faktu płynie wniosek, że wcześniejsza metoda powinna dostarczyć kolejnej metodzie obiekt, na którym będzie mogła być wywołana. Mówiąc prościej, metoda dodaj powinna zwracać obiekt poleceniem return. Obecnie nie zwraca niczego.

Dopiszmy zatem na końcu tej metody polecenie return… Obiekt wewnątrz klasy jest wskazywany przez referencje $this, więc w ten właśnie sposób możemy zwrócić w tej metodzie obiekt: zapisując return $this.

Gotowa metoda powinna wyglądać tak:

	public function dodaj($n)
	{
		$this->a+=$n;
		return $this;
	}

To samo należy zrobić z pozostałymi metodami, za którymi mogą być wywołane inne metody. W zasadzie w każdej metodzie publicznej, gdzie nie występuje jeszcze instrukcja return, lub nie zwraca ona żadnych istotnych informacji, możemy rozważyć zwracanie referencji $this. W przypadku klasy Kalkulator wyjątkiem jest jedynie metoda konstruktora, na której i tak nie da się wywołać kolejnych metod, gdyż wywołana jest ona podczas tworzenia obiektu.

Gotowy kod klasy Kalkulator powinien wyglądać następująco:

<?php
	class Test
	{
		private $a=null;
 
		public function __construct($n)
		{
			$this->a=$n;
		}
 
		public function dodaj($n)
		{
			$this->a+=$n;
			return $this;
		}
 
		public function odejmij($n)
		{
			$this->a-=$n;
			return $this;
		}
 
		public function pomnoz($n)
		{
			$this->a*=$n;
			return $this;
		}
 
		public function podziel($n)
		{
			$this->a/=$n;
			return $this;
		}
 
		public function wynik()
		{
			return $this->a;
		}
	}
 
	$t=new Test(12);
	echo $t->dodaj(8)->podziel(5)->odejmij(1)->pomnoz(3)->dodaj(2)->wynik();
?>

Efektem działania tego kodu będzie wyświetlenie liczby 11.

Jeżeli zainteresował Cię ten artykuł, z pewnością chciałbyś się dowiedzieć również jak i do czego stosować: polimorfizm, składowe statyczne, interfejsy, klasy i metody abstrakcyjne, klasy i metody finalne, przeciążanie pól i metod, oraz kilka innych technik. Zajrzyj do programowania obiektowego w PHP.

Dodaj odpowiedź

Musisz się zalogować aby dodać komentarz.