Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Roznica miedzy interfejsem i klasa abstrakcyjna
Vomit
post
Post #1





Grupa: Zarejestrowani
Postów: 122
Pomógł: 0
Dołączył: 23.01.2006

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


Witam,

Nigdzie nie moge doczytac jaka jest praktyczna roznica miedzy interfejsem i klasa abstrakcyjna. Teorie znam, interfejs definiuje nagłowki metod danej klasy, klasa abstrakcyjna ma wieksze mozliwosci, moze ponadto definiowac zawartosc metody.

Chodzi mi jednak jak to sie sprawdza w praktyce, kiedy zastosowac interfejs a kiedy klase abstrakcyjna, po co tak naprawde mam w ogole definiowac "ogolny zarys" klasy w interfejsie czy klsaie abstrakcyjnej?

Pozdrawiam
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Prph
post
Post #2





Grupa: Zarejestrowani
Postów: 338
Pomógł: 2
Dołączył: 4.03.2006
Skąd: Łódź

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


Nie koniecznie dla innego programisty. Piszac duza aplikacjie (tzn zlozona), w koncu zapomnisz o czyms. Interfejsy ratuja wtedy skore (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Klase definiuje sie jako abstrakcyjna w chwili, kiedy nie chcesz aby ktos utworzyl jej obiekt. Taka klase da sie tylko dziedziczyc, co w praktyce oznacza ze klasa abstrakcyjna nie jest kompletne klasa. Dziedziczenie uzupelnia klase i wtedy mozemy stworzyc dzialajacy obiekt. Pokaze na przykladzie:

Mamy w aplikacji klase wyswietlajaca dane (widok w MVC). Czesto piszemy kilka widokow - np. taki wyswietlajacy dane na podstawie szablonow php. Do tego doliczmy, ze mozemy miec widok wyswietlajacy dane jak leci oraz taki, ktory udekoruje je o cala strone (stopka, naglowek, menu itp.).

Wiadomo, ze takie widoki powinny miec metody taki, jak:

  1. <?php
  2.  
  3. interface IView
  4. {
  5. public function setAttribute($sAttributeName, $mAttributeValue);
  6. public function setAttributesArray($aAttributeArray);
  7.  
  8. public function getAttribute();
  9. public function removeAttribute($sAttributeName);
  10.  
  11. public function __get($sAttributeName);
  12. public function __set($sAttributeName, $mAttributeValue);
  13.  
  14. public function display();
  15. public function fetch();
  16. }
  17.  
  18. ?>


W ten sposob zdefiniowalismy interfejs dla klas widoku. Od tech chwili, kazda implementujaca klasa ten interfejs bedzie musiala je miec.

Ale pomyslmy przez chwile. Czy klasa widoku normalna i dekorujaca nie bedzie miala takich samych metod getAttribute(), removeAttribute(), __set(), __get()? Po co powielac kod - napiszemy klase abstrakcyjna:

  1. <?php
  2.  
  3. abstract class View implements IView
  4. {
  5. private $_aAttributes;
  6.  
  7. public function __construct()
  8. {
  9. $this->_aAttributes = array();
  10. }
  11.  
  12. public function setAttribute($sAttributeName, $mAttributeValue)
  13. {
  14. $this->_aAttributes[$sAttributeName] = $mAttributeValue;
  15. }
  16.  
  17. public function setAttributesArray($aAttributeArray)
  18. {
  19. $this->_aAttributes = array_merge($this->_aAttributes, $aAttributeArray);
  20. }
  21.  
  22. public function getAttribute()
  23. {
  24. if(func_num_args() == 0)
  25. return null;
  26. $aArgs = func_get_args();
  27.  
  28. $aCurrentAttribute = $this->_aAttributes;
  29.  
  30. foreach($aArgs as $sKey => $sAttributeName)
  31. {
  32. if(isset($aCurrentAttribute[$sAttributeName]))
  33. $aCurrentAttribute = $aCurrentAttribute[$sAttributeName];
  34. else
  35. return null;
  36. }
  37.  
  38. return $aCurrentAttribute;
  39. }
  40.  
  41. public function removeAttribute($sAttributeName)
  42. {
  43. if(isset($this->_aAttributes[$sAttributeName]))
  44. unset($this->_aAttributes[$sAttributeName]);
  45. }
  46.  
  47. public function __get($sAttributeName)
  48. {
  49. $aAttributes = explode(_LANGUAGE_SEPARATOR, $sAttributeName);
  50. return call_user_func_array(array($this, 'getAttribute'), $aAttributes);
  51. }
  52.  
  53. public function __set($sAttributeName, $mAttributeValue)
  54. {
  55. $this->setAttribute($sAttributeName, $mAttributeValue);
  56. }
  57.  
  58. public function display()
  59. {
  60. echo $this->fetch();
  61. }
  62. }
  63.  
  64. ?>


Dlaczego klasa musi byc abstrakcyjna:
1. Pominmy slowo kluczowe abstract. Proba utworzenia obiektu tej klasy zakonczy sie bledem. Klasa przeciez nie definiuje metody fetch(), ktora wymusza interfejs.

2. Nie chcemy przeciez utowrzyc (najczesciej przez pomylke) obiektu widoku, ktory nie dziala. Lepiej rozszerzac klase (dziedziczyc od niej). W ten sposob zbudujemy klasy widokow, ktore dzialaja, a maja mniej kodu (bo przeciez dziedzicza z tej klasy abstrakcyjnej).

A jak wyglada przykladowy widok?

  1. <?php
  2.  
  3. class BasicHtmlView extends View
  4. {
  5. private $_sTemplate;
  6.  
  7. public function fetch()
  8. {
  9. if(!isset($this->_sTemplate))
  10. throw new ViewException('The template has not been specyfied');
  11.  
  12. $sTemplateFileName = _DIR_APPLICATION_TEMPLATES . $this->_sTemplate . 'Action.php';
  13.  
  14. if(!is_readable($sTemplateFileName))
  15. throw new ViewException('The template ' . $this->_sTemplate . ' does not exist');
  16.  
  17.  
  18. require_once($sTemplateFileName);
  19.  
  20. $sFetched = ob_get_contents();
  21.  
  22. return $sFetched;
  23. }
  24.  
  25. public function setTemplate($sTemplateName)
  26. {
  27. $this->_sTemplate = $sTemplateName;
  28. }
  29. }
  30.  
  31. ?>


Dodam jeszcze, ze nowy widok nie musi juz implementowac interfejsu, poniewaz dziedziczy implementacje z klasy abstrakcyjnej,

Proste i wygodne (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Pozdrawiam, Adrian.

Ten post edytował Prph 16.07.2006, 10:25:21
Go to the top of the page
+Quote Post

Posty w temacie


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

 



RSS Aktualny czas: 7.10.2025 - 05:23