#1 9. 1. 2009 20:57

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

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

Offline

 

#2 9. 1. 2009 21:59

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

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)

Offline

 

#3 9. 1. 2009 22:05

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

Re: Extend dvou tříd

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

Offline

 

#4 9. 1. 2009 22:31

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

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.

Offline

 

#5 9. 1. 2009 22:33

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

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.

Offline

 

#6 9. 1. 2009 23:30

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

Re: Extend dvou tříd

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

Online

 

#7 9. 1. 2009 23:49

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

Re: Extend dvou tříd

David Grudl napsal(a):

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

To je nižší objektovost :D

Offline

 

#8 10. 1. 2009 17:43

phx
Moderator
Místo: HK
Registrovaný: 17. 4. 2008
Příspěvky: 780
Web

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:)

Offline

 

#9 10. 1. 2009 18:26

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();
        }

        //...
}

Offline

 

#10 10. 1. 2009 19:31

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.

Offline

 

#11 12. 11. 2009 11:32

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

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.

Offline

 

Zápatí