Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [OOP]Funkcja z dowolnym parametrem
Forum PHP.pl > Forum > PHP > Object-oriented programming
HgReed
Witam.
Natknąłem się dzisiaj na taki problem. Zobrazuje to na przykładzie.
  1. abstract class Main {
  2. abstract function __construct();
  3. }
  4.  
  5. class Dziecko_1 extends Main {
  6. function __construct($a, $b) { //Żeby to było możliwe
  7. echo $a.$b;
  8. }
  9. }

Czyli chodzi mi oto - czy klasa dziedzicząca (lub implementująca interfejs) miała dowolny parametr (funkcja musi być 'wymagana')?
Orzeszekk
jak wywalisz abstract function __construct(); to stanie sie to mozliwe. Jak masz abstract w klasie rodzica to implementacje tej metody musza miec idealnie te same parametry.

ewentualnie jesli chcesz strasznie zeby w main zostal ten abstract function __construct to mozesz w Dziecko_1 zrobic tak

public function __construct($a=null, $b=null)
{
if ((is_numeric($a) && is_numeric($b))==false) {throw RuntimeException("BŁędne parametry.")}
}
tez nie powinien krzyczec.
HgReed
Właśnie mi chodzi o to, żeby ta funkcja X była w abstract'ie - musi być wymagana.
Chyba zostaje mi tylko wklepanie array $array = array() jako parametr i sprawdzanie zawartości :/
Crozin
A mógłbyś opisać jaki jest Twój problem? Tj. skąd taki wymóg. Wydaje mi się, że możesz po prostu źle podchodzić do tego już od strony projektowej.
Orzeszekk
Cytat(HgReed @ 26.02.2012, 15:14:25 ) *
Właśnie mi chodzi o to, żeby ta funkcja X była w abstract'ie - musi być wymagana.
Chyba zostaje mi tylko wklepanie array $array = array() jako parametr i sprawdzanie zawartości :/


No to tak jak ci napisałem robisz function coś ( $param1=null, $param2=null) w implementacji, a w abstrakcie robisz
abstract function coś (); i działa.

Choc nie jest to rozwiazanie zbyt eleganckie.

Jesli chcesz rozwiazania poprawnego to mozesz jeszcze utworzyc valueObject - tak jak jest np w eventach javascriptu i C#.

nigdy nie ma event handlerów
function eventHandler(eventID, eventName,x, y, .....)

zawsze jest

function eventHandler(eventArgs).

  1. class PrzodekParameterSet
  2. {
  3. protected $eventName;
  4. public function getEventName() { return $this->eventName; }
  5. public function setEventName($value) { $this->eventName = $value; }
  6. public function __construct($eventName) { $this->setEventName($eventName); }
  7. }
  8.  
  9. abstract class Przodek
  10. {
  11. abstract public function jakasMetoda(PrzodekParameterSet $parameters);
  12. }
  13.  
  14. class Dziecko extends Przodek
  15. {
  16. public function jakasMetoda(PrzodekParameterSet $parameters) { /* tresc */ }
  17. }
  18.  
  19. class DrugieDzieckoParameterSet extends PrzodekParameterSet
  20. {
  21. protected $dodatkowyParam;
  22. public function getDodatkowyParam() { return $this->dodatkowyParam; }
  23. public function setDodatkowyParam($value) { $this->dodatkowyParam = $value;}
  24. public function __construct($eventName, $dodatkowyParam)
  25. {
  26. parent::__construct($eventName);
  27. $this->setDodatkowyParam($dodatkowyParam);
  28. }
  29. }
  30.  
  31. class DrugieDziecko extends Przodek
  32. {
  33. public function jakasMetoda(DrugieDzieckoParameters $parameters)
  34. {
  35. }
  36. }
  37.  
  38.  
  39. $dziecko = new Dziecko();
  40. $dziecko->jakasMetoda(new PrzodekParameterSet("nowy_event"));
  41. $drugieDziecko = new DrugieDziecko;
  42. $drugieDziecko->jakasMetoda(new DrugieDzieckoParameterSet("nowy_event", "dodatkowy_param"));
  43.  


tez powinno chodzic.
Tylko dla mnie definiowanie konstruktora jako abstrakcyjnego jest z deka pozbawione sensu - kazda klasa ma swoj konstruktor (pusty),
i konstruktory w klasach dziedziczacych moga miec rozna liste parametrów.
Natomiast zwykle metody zefiniowane jako abstrakcyjne musza miec taka sama liste parametrów i mozesz to zastosowac.


Nie stosuj tablic (zamiast nich stosuj valueObjecty - to jedna z dobrych praktyk) - po paru miesiacach moze byc problem z odgadnieciem jak ta tablica powinna wygladac. No i w zasadzie nie masz sposobu by wymusic jakis parametr, jezeli jest obowiazkowy.

ja odkad pracuje z php nie mialem powodu by stosowac takie dziwaczne konstrukcje, wiec moze po prostu projekt twoich klas jest blędny i dlatego wymusza takie rozwiazania? moze jego poprawienie rozwiaze problem w prostszy sposob tak jak pisze crozin
HgReed
Te valueObject'y to - jak dla mnie - przerost formy nad treścią.

A temat rozwiązany - "wystarczyło" dopisać sobie 3 funkcje i idzie to obejść.

PS. Ten __construct był tylko przykładem, a nie moim problemem.
Orzeszekk
Cytat(HgReed @ 26.02.2012, 22:00:59 ) *
Te valueObject'y to - jak dla mnie - przerost formy nad treścią.


Tak ci sie tylko wydaje smile.gif

wygenerowanie takiego value objectu w porządnym ide to kilka sekund, a po paru miesiacach pozwalają się połapać o co chodziło.
dobrą praktyką jest zamiana tablic na value objecty w takich sytuacjach.

Wolalbys dostac takie eventArgs jako value object, ładnie podpisane np eventArgs klikniecia myszki: x,y- wspolrzedne, buttonPress- jaki przycisk zostal wcisniety itd itd, czy wolalbys dostac tablicę 20 wartosci w nieznanej kolejnosci i bobrowac dokumentacje który jest który?tongue.gif
A moze ktorys z parametrow to kilkukrotnie zagniezdzona tablica? Hmm.. ile razy ona zagniezdzona byla i co było czym... sytuacje z zycia wziete ;P+dolicz troche czasu na debugowanie przez pomyłki

Mądry autor ksiażki "clean Code" zaleca zamiane tablic na value objecty, zaleca by w tych value objectach nie robic publicznych pól, tylko dostęp do nich był przez gettery/settery i zaleca uzywac getterow/setterow nawet wewnatrz klasy zamiast bezposredniego dostępu do wartosci, i ja sie go słucham bo wiele jego teorii sie sprawdzilo w praktyce. Niewielkim kosztem wydajności która w PHP i tak jest do dupy, uzyskujesz duzo bardziej idiotoodporny kod.
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.