#1 před 3 lety

skocourek
Člen
Registrovaný: 15. 6. 2007
Příspěvky: 200

Extend dvou tříd

Zdravím!

Řešil už někdo situaci, kdy je třeba extendovat dvě třídy?

Konkrétně – pracuju na projektu, kde je www sekce postavena na Nette, komunikace s databází není přes db layer, ale přes námi psanou třídu. Tato třída extenduje SoapClient (což je interní třída PHP), ale zároveň by bylo fajn, kdyby mohlo extendovat Object (kvůli fičurkám).

Má toto nějaké řešení?

Thx

 

#2 před 3 lety

LM
Člen
Registrovaný: 11. 3. 2008
Příspěvky: 263

Re: Extend dvou tříd

A co něco jako:

class MySoapClient extends Nette\Object
{
        /** @var SoapClient */
        private $soapClient;

        …

        public function __call($name, $args)
        {
                $cb = array($this, $name);

                if (is_callable($cb)) { // i když u SoapClient to bude asi vždy TRUE, má __call :-/
                        call_user_func_array($cb, $args);
                } else {
                        parent::__call($name, $args);
                }
        }

        // … __set, __get?
}

Problém je že takovou třídu nelze považovat za potomka SoapClient, i když se chová skoro totožně.

Editoval LM (9. 1. 2009 22:03)

 

#3 před 3 lety

skocourek
Člen
Registrovaný: 15. 6. 2007
Příspěvky: 200

Re: Extend dvou tříd

Tedy, nechci vypadat jako negramota, ale nějak to nechápu…

 

#4 před 3 lety

LM
Člen
Registrovaný: 11. 3. 2008
Příspěvky: 263

Re: Extend dvou tříd

Tímto by tvoje třída měla vlastnosti třídy Nette\Object a zároveň by všechny volané metody dál předávala vnitřnímu SoapClient.

 

#5 před 3 lety

skocourek
Člen
Registrovaný: 15. 6. 2007
Příspěvky: 200

Re: Extend dvou tříd

Hm, vzhledem k tomu, že sama o sobě je moje třída dosti složitá, je to dost krkolomné řešení. Budeme se muset vzdát předka Object… Ale to nevadí, trochu jsem s tím počítal, jen jsem to zkusil, jestli náhodou někdo nezná řešení, aby třída měla dva „plnohodnotné“ rodiče.

 

#6 před 3 lety

David Grudl
Administrator
Registrovaný: 8. 2. 2005
Příspěvky: 5548

Re: Extend dvou tříd

To (naštěstí) v PHP nejde.

 

#7 před 3 lety

LM
Člen
Registrovaný: 11. 3. 2008
Příspěvky: 263

Re: Extend dvou tříd

David Grudl napsal(a):

To (naštěstí) v PHP nejde.

To je nižší objektovost :D

 

#8 před 3 lety

phx
Moderator
Registrovaný: 17. 4. 2008
Příspěvky: 878

Re: Extend dvou tříd

Domnivam se, ze reseni od LM by mohlo byt OK. But se zavola metoda Objektu a nebo one druhe tridy. Otazka je nutne dedit? Neslo by jen tvou tridou interne vyuzivat tu druhou. Myslim tim, ze by mela interni instanci kterou by vyuzivala dle potreby.

Jinak „prasacke reseni“ je zkopirovat metody z Object do te tvoji tridy. Moc jich neni:)

 

#9 před 3 lety

Imerix
Člen
Registrovaný: 10. 1. 2009
Příspěvky: 2

Re: Extend dvou tříd

Myslím, že řešením může být:

class MySoap extends Object
{
        protected $soap;
        //...

        public function __construct($wsdl,$options)
        {
                $this->soap = new SoapClient($wsdl,$options);
                //...
        }

        public function __call($method,$args)
        {
                // Následující kód provede POUZE requesty na server:
                return $this->soap->__soapCall($method,$args);
        }

        // Libovolně lze pak přidat další metody SoapClienta, například:
        public function __getFunctions()
        {
                return $this->soap->__getFunctions();
        }

        //...
}

 

#10 před 3 lety

Václav Vaník
Člen
Registrovaný: 7. 1. 2009
Příspěvky: 3

Re: Extend dvou tříd

Tak to máš samozřejmě špatnej návrh :D
Na manipulační featurky použij návrhovej vzor adapter, takže pak nebude problém vyměnit soap třeba za db.

 

#11 před 2 lety

pete
Člen
Registrovaný: 22. 10. 2009
Příspěvky: 25

Re: Extend dvou tříd

Zdedit z dvoch tried sa neda kvoli tzv. ‚Diamond problem‘, v jednoduchosti diamond problem vznika ak classA a aj classB ma metodu getFoo(), classC zdedi z oboch tried (classA a classB) ale je tam problem ktoru getFoo() metodu pouzit/zdedit. Niektore jazyky (Python, Perl etc.) povoluju dedit aj z viacerych tried a riesia to tymyto sposobmi:
http://en.wikipedia.org/…mond_problem

Ako uz niekto navrhol, pouzi adapter design pattern, alebo pouzivaj interface, v pripade pouzitia interface mozes implementovat viac ako jeden interface, pretoze telo metody nieje specifikovane v interface, takze diamond problem nevznikne.

 

Zápatí