Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dziedziczenie po klasie abstrakcyjnej ...
Forum PHP.pl > Forum > PHP
jacekkobus
Czesc.

Czy ktos z Was spotkal sie moze z "problemem" (nie wiem, czy moja taktyka jest dobra, dlatego w cudzyslowiu) dziedziczenia po klasie abstr., ktory polega na tym, iz w momencie nadpisania metody klasa potomna musi uzyc parametrow zadeklarowanych w klasie nadrzednej ?

Dokladnie chodzi mi o:

  1. abstract class Zwierze
  2. {
  3. protected function nakarm( $zarcie )
  4. { (...) }
  5. }
  6.  
  7. class Pies extends Zwierze
  8. {
  9. public function nakarm( $zarcie, $przystawka )
  10. {
  11. //(Zrob cos z przystawka i dopiero nakarm)
  12. return parent::nakarm( $zarcieZPrzystawka );
  13. }
  14. }


Powyzszy przyklad zwraca Strict'a:
[i]Strict Standards: Declaration of Pies ::nakarm() should be compatible with that of Zwierze [...][/i

Czy to jest zly przyklad uzycia klasy abstrakcyjnej ?

Jesli Zwierze nie byla by abstrakcyjna, to rozwiazuje problem. Moge nadpisywac metody, ale to rozwiazanie jest zle w moim wypadku. To musi byc klasa abstrakcyjna.
nexis
Klasa dziedzicząca po klasie abstrakcyjnej musi posiadać dokładnie takie same metody z dokładnie tymi samymi parametrami. Taki jest jej sens, więc prawdopodobnie źle zaprojektowałeś system, skoro jest to dla Ciebie przeszkodą.
cojack
Kolega jacek chyba nie wiem o tym że nie można utworzyć obiektu klasy abstrakcyjnej, więc hermetyzacja metod w tejże klasie jest bezcelowa.
dr_bonzo
Nadpisywanie metod to po prostu zmiana ich i tylko IMPLEMENTACJI. Inna lista paremtrow w metodzie == INNA METODA.

Inna kwestia jest ze php nie pozwoli ci dodac kilku metod o tej samej nazwie, z inna lista parametrow (to nie Java, C#, C, ....).
Quider
jak chcesz implementowac różne metody dla róznych zwierząt tylko pozostawiając jednakowe nazwy - uzyj interfaców
krowal
Quider nie masz racji smile.gif takie coś nie zadziała:
  1. <?php
  2. interface iTest{
  3. public function doSomething($p1, $p2);
  4. }
  5.  
  6. class Tester implements iTest{
  7. public function doSomething($p1){
  8. echo 'i dont want to cooperate ;)';
  9. }
  10. }
  11. ?>
jacekkobus
Cytat(nexis @ 4.09.2009, 09:44:20 ) *
Klasa dziedzicząca po klasie abstrakcyjnej musi posiadać dokładnie takie same metody z dokładnie tymi samymi parametrami. Taki jest jej sens, więc prawdopodobnie źle zaprojektowałeś system, skoro jest to dla Ciebie przeszkodą.


A moge nadpisac konstruktor klasy abstrakcyjnej zmieniajac przy tym parametry ? Pozniej pozostaje wywolanie parent::__construct( [...] );

Cytat(cojack @ 4.09.2009, 10:43:03 ) *
Kolega jacek chyba nie wiem o tym że nie można utworzyć obiektu klasy abstrakcyjnej, więc hermetyzacja metod w tejże klasie jest bezcelowa.


Wyjasnij. Jesli dobrze rozumiem, hermetyzacja polega na ukrywaniu pol lub metod danej klasy w taki sposob, aby byly one widoczne tylko dla klas zaprzyjaznionych badz, tak jak w moim wypadku, klasy potomnej.

Interfejs zewnetrzny klasy ktorej instancja zostala stworzona czesto nie potrzebuje wszystkich metod, ktore zawarte sa w klasie abstrakcyjnej, wiec po co ma miec do nich dostep ?

Jesli juz jestesmy przy mechanice dzialania ukadu trawiennego zwierzat, to po co mi w interfejsie zewnetrznym "psa', w ktorym przyjmuje jedzenie, metoda odpowiadajaca za trawienie danego pokarmu smile.gif ? Taka metoda moze byc zawarta w klasie abstrakcyjnej z typem dostepu "protected".

Moze ja cos zle rozumiem.
Zyx
Co do hermetyzacji, to się nie zgodzę z przedmówcą. Owszem, nie można utworzyć obiektu klasy abstrakcyjnej, ale można utworzyć obiekt klasy dziedziczącej po klasie abstrakcyjnej i uważam, że ze względu na właśnie ten obiekt byłoby miło taką klasę abstrakcyjną zahermetyzować odpowiednio.

Zmiana prototypu metody -> generalnie można to robić:

  1. <?php
  2.  
  3. class A
  4. {
  5. public function foo($a, $b)
  6. {
  7. echo 'A::foo('.$a.', '.$b.')<br/>';
  8. } // end foo();
  9. }
  10.  
  11. class B extends A
  12. {
  13. public function foo($a)
  14. {
  15. parent::foo($a, 5);
  16. echo 'B::foo('.$a.')<br/>';
  17. } // end foo();
  18. }
  19.  
  20. // działa, lecz wywołuje się cały czas metoda B::foo()
  21. $obj = new B;
  22. $obj->foo(3, 6);
  23. $obj->foo(5);


Nie jest to jednak zalecane, tj. PHP zgłasza wtedy komunikat E_STRICT. Jeśli jednak przed A::foo() dopiszemy słówko kluczowe abstract, albo taką metodę zadeklarujemy w interfejsie, diametralnie zmienia to postać rzeczy. Wtedy przy próbie użycia innego prototypu niż zadeklarowany dostaniemy ten sam komunikat, co poprzednio, ale już o statusie błędu krytycznego.
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.