Jak získat data z proměnné od svého potomka

Karman

Jak získat data z proměnné od svého potomka
« kdy: 22. 04. 2014, 16:55:20 »
Ahoj, jak můžu získat z class (class Tata která rodičem class Syn) obsah proměnné z class Syn? Pozor! ne opačně. Díky za pomoc

class Tata {
   protected function __construct(){
      echo $var;
   }
}

class Syn {
   protected $var;
   protected function __construct(){
     Tata:__construct();
   }
}



perceptron

Re:Jak získat data z proměnné od svého potomka
« Odpověď #1 kdy: 22. 04. 2014, 17:16:59 »
skuste dat praktickejsi priklad, lebo toto smrdi velmi zlym navrhom


Sten

Re:Jak získat data z proměnné od svého potomka
« Odpověď #2 kdy: 22. 04. 2014, 17:28:03 »
Většinou se to dělá abstraktní metodou, kterou ten potomek implementuje. Ale možná máte jen špatný návrh.

Karman

Re:Jak získat data z proměnné od svého potomka
« Odpověď #3 kdy: 22. 04. 2014, 17:28:40 »
Oprava kódu...

Kód: [Vybrat]
class Tata {
   protected function __construct(){
      echo $var;
   }
}

class Syn extends Tata {
   protected $var;
   protected function __construct(){
     Tata:__construct();
   }
}

Ivorne

Re:Jak získat data z proměnné od svého potomka
« Odpověď #4 kdy: 22. 04. 2014, 17:43:29 »
Takže PHP?

No vpodstatě by to mělo jít rámcově tak, jak to děláš. Prostě dáš 'echo $this->var;' a mělo by to ject (nevím úplně jistě, jestli to bude fungovat v konstruktoru - kdyžtak to zkus hodit do nějaké jiné metody). Viz http://stackoverflow.com/questions/1147109/type-casting-for-user-defined-objects.

Tyhle postupy á la dynamické přetypování ale nebývají nejlepším řešením problému. Problém je tak nějak v tom, že v rodiči Tata nevíš, jestli se skutečně jedná o instanci potomka Syn nebo nějakého jiného. To samozřejmě můžeš vyřešit nějakou podmínkou, ale to už zahazuješ výhody objektového programování a měl bys lepší to vůbec neřešit objektově.

Typicky se tohle dá řešit buď tak, že proměnnou $var nadefinuješ v rodiči Tata a každý potomek si do ní nacpe co chce. Takže když pak Tata vypíše tu svojí proměnnou, tak je obsah proměnné určený pouze třídou potomka.

Druhá možnost, jak tyhle problémy řešit je tak, že si v rodiči Tata nadefinuješ metodu (například getVar) a tu přetížíš v potomkovi Syn. Takže v Tata bude 'function getVar(){}' a v Syn bude např 'function getVar(){return "la la la, já jsem Syn";}'. Takže jsi poět v situaci, kdy si pouze potomek řídí, co je v proměnné získané voláním getVar.


squirrel

Re:Jak získat data z proměnné od svého potomka
« Odpověď #5 kdy: 22. 04. 2014, 17:47:06 »
a vyladit do zlatova se druha moznost da takhle:

 
Kód: [Vybrat]
Tata::getVar()
{
    throw new Exception("Nepretizils metodu getVar!!! :)");
}

Sten

Re:Jak získat data z proměnné od svého potomka
« Odpověď #6 kdy: 22. 04. 2014, 17:54:48 »
a vyladit do zlatova se druha moznost da takhle:

 
Kód: [Vybrat]
Tata::getVar()
{
    throw new Exception("Nepretizils metodu getVar!!! :)");
}

Aneb proč to dělat jednoduše, když to jde složitě :D

Kód: [Vybrat]
class Tata
{
    abstract function getVar();
}

FrostyX

Re:Jak získat data z proměnné od svého potomka
« Odpověď #7 kdy: 22. 04. 2014, 18:42:02 »
Citace
Kód: [Vybrat]
class Syn extends Tata {

Položil bych si základní otázku. "Je každý syn tátou?" - odpovím si sám, není. Tady dědičnost prostě nepatří. Pokud se snažíš o to, abys o každém synovi mohl říci, kdo je jeho táta, přidej třídě Syn atribut. Ekvivalentně třídě Tata můžeš přidat atribut děti.

Re:Jak získat data z proměnné od svého potomka
« Odpověď #8 kdy: 22. 04. 2014, 19:15:04 »
Syn implements tata, mama ?

Sten

Re:Jak získat data z proměnné od svého potomka
« Odpověď #9 kdy: 22. 04. 2014, 19:45:18 »
Citace
Kód: [Vybrat]
class Syn extends Tata {

Položil bych si základní otázku. "Je každý syn tátou?" - odpovím si sám, není. Tady dědičnost prostě nepatří. Pokud se snažíš o to, abys o každém synovi mohl říci, kdo je jeho táta, přidej třídě Syn atribut. Ekvivalentně třídě Tata můžeš přidat atribut děti.

Pravděpodobně jde jen o chybu terminologie a OP měl na mysli předka a potomka.

eMko

  • ****
  • 456
    • Zobrazit profil
    • E-mail
Re:Jak získat data z proměnné od svého potomka
« Odpověď #10 kdy: 22. 04. 2014, 20:05:40 »
Aneb proč to dělat jednoduše, když to jde složitě :D

Kód: [Vybrat]
class Tata
{
    abstract function getVar();
}

Z třídy, která má abstraktní metodu, nelze instanciovat objekt. (Pokud to v PHP jde, tak je to ještě větší sračka než jsem si dosud myslel.)

To, co je v tomto případě potřeba, je metoda virtuální - to ale PHP neumožňuje. Proto ji normálně implementuj v rodičovské třídě s nějakým výchozím chováním (= vrátí výchozí hodnotu; např. prázdný řetězec (jedná-li se o řetězcovou proměnnou), 0 pokud je to číselná hodnota a sčítáš/odčítáš ji, 1 pokud násobíš ...), v extrémním případě výjimku nebo null. V potomkovi potom override a do komentáře k rodičovské třídě to napsat.

Nicméně v prvé řadě bych se zabýval otázkou "Pokud objekt jedné třídy potřebuje přistupovat k hodnotě potomka, proč jednoduše tuto hodnotu nedat do rodičovské třídy?" Pak se můžeš dostat do situace, kdy v metodách v předkovi bude tuna kódu zabývající se tím, jestli nějaká metoda je správně implementovaná či nikoliv a spíš než cokoliv jiného z toho může snadno vzniknout totální brajgl.

Měnit části chování pomocí abstraktních/virtuálních metod, to se dělá celkem často. Ale přistupovat z předka do proměnné v nějakém potomkovi ... to smrdí špatným návrhem.

WakeUp

Re:Jak získat data z proměnné od svého potomka
« Odpověď #11 kdy: 22. 04. 2014, 23:18:10 »
Z třídy, která má abstraktní metodu, nelze instanciovat objekt. (Pokud to v PHP jde, tak je to ještě větší sračka než jsem si dosud myslel.)

To, co je v tomto případě potřeba, je metoda virtuální - to ale PHP neumožňuje. Proto ji normálně implementuj v rodičovské třídě s nějakým výchozím chováním (= vrátí výchozí hodnotu; např. prázdný řetězec (jedná-li se o řetězcovou proměnnou), 0 pokud je to číselná hodnota a sčítáš/odčítáš ji, 1 pokud násobíš ...), v extrémním případě výjimku nebo null. V potomkovi potom override a do komentáře k rodičovské třídě to napsat.

Virtualna metoda je abstraktna metoda s defaultnou implementaciou. PHP virtualne metody podporuje, v PHP su vsetky metody implicitne virtualne:

Kód: [Vybrat]
class Rodic
{
    function __construct() { echo $this->getVar(); }
    function getVar() {}
}

class Potomok extends Rodic
{
    private $var = 'hodnota';
    function getVar() { return $this->var; }
}

$potomok = new Potomok();

Ivorne

Re:Jak získat data z proměnné od svého potomka
« Odpověď #12 kdy: 23. 04. 2014, 00:19:12 »
No virtuální metoda je metoda, která se linkuje dynamicky pomocí virtuální tabulky. A v PHP jsou všechny metody virtuální. Abstraktní metoda je, že se třída nedá instancovat. Použiješ to, pokud se ti to prostě hodí.

tonda_

Re:Jak získat data z proměnné od svého potomka
« Odpověď #13 kdy: 23. 04. 2014, 10:00:41 »
Jake by se implementovala v OOP rodina knizete Kroka?

on mel za dceru tetu, takze ji musel mit se svoji babickou



Kit

Re:Jak získat data z proměnné od svého potomka
« Odpověď #14 kdy: 26. 04. 2014, 09:10:02 »
Citace
Kód: [Vybrat]
class Syn extends Tata {

Položil bych si základní otázku. "Je každý syn tátou?" - odpovím si sám, není. Tady dědičnost prostě nepatří. Pokud se snažíš o to, abys o každém synovi mohl říci, kdo je jeho táta, přidej třídě Syn atribut. Ekvivalentně třídě Tata můžeš přidat atribut děti.

Pravděpodobně jde jen o chybu terminologie a OP měl na mysli předka a potomka.
Je tedy každý potomek předkem?