Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wywoływanie abstrakcyjnej metody dziecka w operacji rodzica
Forum PHP.pl > Forum > PHP > Object-oriented programming
starach
  1. <?php
  2. abstract class Rodzic
  3. {
  4.    /**
  5.      * Operacja wykorzystywana przez potomstwo
  6.      */
  7.    public static function operacja()
  8.    {
  9.        echo self::innaOperacja();
  10.    }
  11.    /**
  12.      * Wymagana operacja do zaimplementowania przez dziecko
  13.      */
  14.    abstract public static function innaOperacja();
  15. }
  16. class Dziecko extends Rodzic
  17. {
  18.    public static function innaOperacja()
  19.    {
  20.        return 'Dane indywidualne dla każdego dziecka.';
  21.    }
  22. }
  23. // Wywoła błąd:
  24. // Fatal error: Cannot call abstract method Rodzic::innaOperacja()
  25. Dziecko::operacja();
  26. ?>
Jak ten problem rozwiązać? worriedsmiley.gif
nevt
to nie ma prawa zadziałać
a dlaczego nie po prostu:
  1. <?php
  2. abstract class Rodzic
  3. {
  4.    abstract public static function operacja();
  5. }
  6.  
  7. class Dziecko extends Rodzic
  8. {
  9.    public static function operacja()
  10.    {
  11.        return 'Dane indywidualne dla każdego dziecka.';
  12.    }
  13. }
  14.  
  15. echo Dziecko::operacja();
  16. ?>
questionmark.gif
starach
Metoda operacja jest podzielona na 5 innych z czego niektóre wywołują się rekurencyjnie i generalnie cała struktura jest cholernie skomplikowana. Natomiast klas dzieci będzie blisko 15, więc chyba zgodzisz się że kompletnym bezsensem i wręcz błędem było by przenoszenie tej implementacji. Oprócz tego istnieje konieczność udostępnienia wartości zwracanej przez metodę innaOperacja(). Inne drogi nie ma. Trzeba w tym kierunku poprzez dziedziczenie i abstrakcję to zrobić.

edit>
To znaczy zapewne inna droga jest, inaczej nie byłoby sensu tutaj pytać, ale dziedziczenia raczej użyć trzeba.
nevt
czy te metody muszą być statyczne questionmark.gif - bo jeżeli tak, to problem jest nie do rozwiązania (przynajmniej ja go nie widzę)...
a jeżeli nie, to wewnątrz operacja() dajesz odwołanie $this->innaOperacja() i wtedy woła ci funkcję odpowiednią dla dla instancji obiektu...
plurr
w pewnej bibliotece użłem tego samego rozwiązania - i działa.
Jednakże nie korzystam z metod statycznych - może w tym tkwi problem ?
guerito
Ten bład jest spowodowany użyciem eslf::. Jeżeli metoda nie musi być statyczna to jak wcześniej wspomniano powinieneś użyć $this zamiast self::. Jeżeli musi być statyczna to skorzystaj z reflectionClass. Tworzysz obiekt reflectionClass od $this pobierasz z niego swoją metodkę i ją wywołujesz. W manualu jest przykład. Powinno zadziałać w twoim przypadku.
iro88
Odgrzeję, bo nie bardzo rozumiem jak wykonać metodę dziecka z poziomu rodzica.
Mam plik index.php który sprawdza url i jeśli jest jakaś 'akcja' to ją wykonuje, a następnie wyświetla 'widok'. Wszystko gra, tylko w każdym z kontrolerów muszę powielać funkcję:
  1. public function doAction() {
  2. if (!empty($_GET['a'])) {
  3. $a = $this->filterString($_GET['a']);
  4. } else { $a = null;}
  5.  
  6. if ($a != null) {
  7. if (method_exists($this,$a)) {
  8. $this->$a();
  9. }
  10. }
  11. }

i na początku, każdego z widoków wykonywać tą funkcję. Chcąc ograniczyć ilość kodu, postanowiłem stworzyć główny kontroler aplikacji i dziedziczyć jego funkcje w pozostałych kontrolerach. Jednak nie mam pojęcia czy w ogóle jest możliwe dynamiczne wykonywanie metod dzieci z poziomu rodzica, a jeśli tak, to nie do końca wiem jak. Za wszelkie wskazówki, fragmenty kodu, dziękuję.

Edit:
Ok. Zanim zadam pytanie popróbuję najpierw 'na idiotę'. A więc: nie rozumiem, lecz spróbowałem wywołać metodę powyższym skryptem i... działa blink.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.