Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Strict Standards
likemandrake
post
Post #1





Grupa: Zarejestrowani
Postów: 175
Pomógł: 17
Dołączył: 23.06.2006

Ostrzeżenie: (0%)
-----


Witam

Mam taki mini problem, mam o to taki zestaw klas:

  1. <?php
  2. class A {
  3.   // Zestaw metod
  4. }
  5.  
  6. class B extends A {
  7.   // Dodatkowy zestaw metod
  8. }
  9.  
  10. abstract class C {
  11.   public function setObject(A $object) {
  12.      
  13.   }
  14. }
  15.  
  16. abstract class D extends class C {
  17.   public function setObject(B $object) {
  18.      
  19.   }
  20. }
  21.  
  22. class Concrete extends class D {
  23.  
  24. }
  25. ?>


Gdy działam na obiekcie klasy Concrete, php wywala mi taki komunikat:
Cytat
Strict Standards: Declaration of D::setObject() should be compatible with that of C::setObject() in [...]


Co o tym myślicie, czy nie jest to troszkę na wyrost? Wiadomo, co chciałem przez to osiągnąć... Jak do tego podejść tak w ogóle?

Pozdrawiam

Ten post edytował likemandrake 3.02.2009, 19:46:48


--------------------
serwiswww.pl
Go to the top of the page
+Quote Post
ayeo
post
Post #2





Grupa: Przyjaciele php.pl
Postów: 1 202
Pomógł: 117
Dołączył: 13.04.2007
Skąd: 127.0.0.1

Ostrzeżenie: (0%)
-----


Nie rozumiem pytania. Co jest na wyrost? Od tego są klasy abstrakcyjne, żeby je potem rozszerzać w klasach potomnych. I tyle. Jak deklarujesz metodę w funkcji abstrakcyjnej to klasa dziedzicząca musi implementować tą metodę. Tak to działa.

Pozdrawiam!


--------------------
Go to the top of the page
+Quote Post
230005
post
Post #3





Grupa: Zarejestrowani
Postów: 316
Pomógł: 36
Dołączył: 2.04.2008

Ostrzeżenie: (0%)
-----


Zdaje się, że obie metody setObject() powinny przyjmować jako argument ten sam typ, a u ciebie to A i B :]
Go to the top of the page
+Quote Post
likemandrake
post
Post #4





Grupa: Zarejestrowani
Postów: 175
Pomógł: 17
Dołączył: 23.06.2006

Ostrzeżenie: (0%)
-----


Dokładnie wiem jak to działa smile.gif Proszę zwrócić uwagę na deklarację metody setObject klasy C i D i zaznaczam, że nie są to metody abstrakcyjne. Rozumiem, jakby metoda setObject w klasie C została zadeklarowana jako abstrakcyjna, to PHP mógłby rzeczywiście u mnie wymagać 100% kompatybilności, a tak to są zwykłe metody, tyle że w klasach abstrakcyjnych.

Cytat(230005 @ 3.02.2009, 20:38:42 ) *
Zdaje się, że obie metody setObject() powinny przyjmować jako argument ten sam typ, a u ciebie to A i B :]


No właśnie, PHP mi nakazuje aby te metody były ze sobą kompatybilne, mimo tego, że nie są to metody abstrakcyjne. Stąd moje pytanie, jak do tego podejść.

Po za tym jak widać klasa B dziedziczy po klasie A....


--------------------
serwiswww.pl
Go to the top of the page
+Quote Post
ayeo
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 1 202
Pomógł: 117
Dołączył: 13.04.2007
Skąd: 127.0.0.1

Ostrzeżenie: (0%)
-----


Witam!

Faktycznie moje niedopatrzenie. Wygląda to na błąd PHP w sumie. Dziwna sprawa smile.gif

Pozdrawiam!


--------------------
Go to the top of the page
+Quote Post
likemandrake
post
Post #6





Grupa: Zarejestrowani
Postów: 175
Pomógł: 17
Dołączył: 23.06.2006

Ostrzeżenie: (0%)
-----


Ściągnąłem ograniczenie abstract z klasy C i D i komunikat pojawia się nadal. Dopiero, gdy w metodzie D::setObject() zmienię przyjmowany parametr na A, PHP nie warczy, a tego nie mogę tak zrobić.

Wniosek z tego taki, że PHP w wersji 5.2.6 ma taki specyficzny błąd.

Czy mógłby ktoś przetestować taki zestaw klas w PHP 5.2.8?
Zaznaczam, że przed wczytaniem pliku z zestawem klas z powyższego kodu musimy ustawić raportowanie błędów na 'E_ALL | E_STRICT'.


--------------------
serwiswww.pl
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #7





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Cytat
No właśnie, PHP mi nakazuje aby te metody były ze sobą kompatybilne, mimo tego, że nie są to metody abstrakcyjne. Stąd moje pytanie, jak do tego podejść.

W php nie ma przeciazania metod (ta sama nazwa a inne parametry) - wiec nadpisujesz metode w podklasie (zmieniasz jej implementacje), a wiec musza miec te same paramery.

Skoro ja nadpisujesz to musisz zachowac jej sygnature - typ parametru (skoro go specyfikujesz), czemu?
Z definicji OOP:
  1. <?php
  2. $c = new Concrete_C(); // extends C
  3. $c->setObject( new A() ); // OK
  4. ?>


Tworzysz sobie obiekt typu C (czyli klasy C lub pochodnych == klasy C, D, Concrete, whatever).
Zgodnie z polimorfizmem mozesz wymienic obiekt na inna podklase klasy C, i powinienes miec mozliwosc wykonywania na nim tych samych operacji,
tu: przekazania obiektu klasy A do metody setObject(), ale

  1. <?php
  2. $c = new Concrete_D(); // extends D
  3. $c->setObject( new A() ); // !!! NIE ZADZIALA, bo A nie jest B (dziedziczenie to relacja odwrotna, B jest A)
  4. ?>



Wiem ze PHP to nie Java/C# i ze jest dynamicznym jezykiem, ale po co w takim razie korzystasz z type-hintingu skoro nie chcesz sie do jego zasad dostosowac?

  1. <?php
  2. // phph 5.2.6
  3. error_reporting( E_ALL | E_STRICT );
  4.  
  5. class A {
  6.    var $x = 3;
  7.  // Zestaw metod
  8.  protected $object = null;
  9. }
  10.  
  11. class B extends A {
  12.  // Dodatkowy zestaw metod
  13. }
  14.  
  15. abstract class C {
  16.  public function setObject(A $object) {
  17.     $this->object = $object;
  18.  }
  19. }
  20.  
  21. abstract class D extends C {
  22.  public function setObject(B $object) {
  23.     $this->object = $object;    
  24.  }
  25. }
  26.  
  27. class Concrete extends D {
  28.  
  29. }
  30. class Concrete_D extends  D {
  31.  
  32. }
  33. class Concrete_C extends C {
  34.  
  35. }
  36.  
  37. $c = new Concrete_C();
  38. $c->setObject( new A() );
  39.  
  40. print_r( $c );
  41.  
  42. $c = new Concrete_D();
  43. $c->setObject( new B() );  // przyjmuje tylko B
  44. $c->setObject( new A() );  // z A nie zadziala
  45.  
  46. print_r( $c );
  47. ?>



// pomógł++
// ayeo


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
likemandrake
post
Post #8





Grupa: Zarejestrowani
Postów: 175
Pomógł: 17
Dołączył: 23.06.2006

Ostrzeżenie: (0%)
-----


Programowałem w C++ i rzeczywiście jeśliby klasy które napisałem powyżej przestawić na ten język, klasa D zawierałaby dwie wersje metod (taką która przyjmuje obiekty klasy A, oraz taką która przyjmuje obiekty klasy B ).

To by wszystko wyjaśniało, dlaczego tak się dzieje w PHP, możnaby sobie powiedzieć, że z powodu braku funkcji przeładowywania metod, programiści mogliby rozwiązać ten problem inaczej smile.gif

Cóż najlepszym w takim wypadku będzie w metodzie klasy D przyjmować parametr typu A, oraz rzucać wyjątek w metodzie, jeśli nie przekazano obiektu klasy B.

Pozdrawiam

Ten post edytował likemandrake 3.02.2009, 21:37:19


--------------------
serwiswww.pl
Go to the top of the page
+Quote Post
Crozin
post
Post #9





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


A czy przypadkiem klasy A i B nie mogłby implementować jakiegoś interfaceu, a metoda setObject mieć sygnaturę public setObject(myInterface)? Chyba, że te dwa obiekty mają robić coś zupełnie innego, ale wtedy możnaby zacząć się zastanawiać czy aby napewno to co robisz jest poprawne?
Go to the top of the page
+Quote Post
likemandrake
post
Post #10





Grupa: Zarejestrowani
Postów: 175
Pomógł: 17
Dołączył: 23.06.2006

Ostrzeżenie: (0%)
-----


Tak, mam interfejs, po którym dziedziczy podana wyżej klasa C.

Klasa A, jest to klasa z pakietu Zend Framework, klasa B jest moją klasą, która rozszerza o pare dodatkowych funkcji klasę A.

Znów klasa D dziedziczy po klasie C, ale w porównaniu do klasy C, klasa D korzysta z dodatkowych funkcji nadanych w klasie B.

Efekt jest taki, że klasa, która tu w ogóle nie jest opisana, wymagająca w/w interfejsu, dostaje to co chce i w taki sposób jak powinna. Dane na których wspomniana nieopisana klasa operuje są przygotowane w lepszy sposób przy użyciu zestawu D i B, niż gwarantowałby mi to zestaw C i A.

Pozdrawiam


--------------------
serwiswww.pl
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.08.2025 - 23:32