Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V  < 1 2  
Reply to this topicStart new topic
> OOP. Interfejsy oraz klasy abstrakcyjne, Zabezpieczenie przed programistą?
Sedziwoj
post 13.05.2007, 11:42:17
Post #21





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


menic stosowane są takie przykłady, aby każdy czytający je zrozumiał, bo pamiętaj że programiści zajmują się różnymi sprawami i nie zrozumiał byś pewnych przykładów.
Dlatego się tworzy takie abstrakcyjne przykłady, a powinieneś je znajdywać w swoim projekcie.


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
Turgon
post 15.05.2007, 18:12:19
Post #22





Grupa: Zarejestrowani
Postów: 800
Pomógł: 0
Dołączył: 26.11.2005
Skąd: Nowy Sącz

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


Cysiaczek, a jakże dobry i prosty przykład. Tutaj warto stosować zasadę "Filtrowuj wszystko co się da". Dlatego na pewno nikt nie wrzuci nam np. do rejestru kolekcji obiektu routera winksmiley.jpg


--------------------
Jah Music Is On My Mind !
Go to the top of the page
+Quote Post
splatch
post 22.05.2007, 14:13:41
Post #23





Grupa: Zarejestrowani
Postów: 487
Pomógł: 7
Dołączył: 7.01.2004
Skąd: Warszawa

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


Troszkę inny przykład ...
  1. <?php
  2. // Definicje wspólne dla wielu obiektów
  3. interface ILiveSchoolElement {} // na codzień w szkole
  4. interface IPeople {} // jakaś osoba
  5. interface ITeacher extends IPeople {} // nauczyciel
  6. interface ILearner extends IPeople {} // uczeń
  7.  
  8. // Implementacja metod wspólnych
  9. abstract class AbstractPeople implements IPeople {}
  10. abstract class AbstractPeopleLiveSchoolElement extends AbstractPeople implements ILiveSchoolElement {}
  11.  
  12. // Specjalizacja, implementacja metod specyficznych
  13. class Teacher extends AbstractPeopleLiveSchoolElement implements ITeacher {}
  14. class Learner extends AbstractPeopleLiveSchoolElement implements ILearner {}
  15.  
  16. // i może na końcu ..
  17. class Jacek extends Learner {}
  18. ?>


--------------------
Łukasz Dywicki
Independent Java and open source software consultant.
Blog - Java, OSGi, integracja oprogramowania..
Go to the top of the page
+Quote Post
LBO
post 22.05.2007, 15:23:35
Post #24





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


JA bym się przyczepił do jacka, bo:
  1. <?php
  2. $jacek = new Learner();
  3. ?>


Hehehe, pozdrawiam, ładny przykład.
Go to the top of the page
+Quote Post
DeyV
post 24.05.2007, 09:34:11
Post #25





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Korzystanie z interfejsów pokazuje swoje zalety w PHP szczególnie dzięki zastosowaniu SPL.
Wykorzystanie iteratora (czyli użycie foreach) lub zliczania elementów (count()) na obiekcie nie byłoby nigdy możliwe, gdyby nie odpowiednie interfejsy, wbudowane i wymagane przez te konstrukcje językowe lub funkcje.

Mi natomiast zasadność użycia interfejsów świetnie pokazała jeszcze inna sytuacja.

Mam różne rodzaje list pobieranych z baz danych. Niektóre z nich można sortować, inne stronnicować, jeszcze inne - filtrować. Niektóre mogą wszystko smile.gif
Do każdego z tych zastosowań mam inną klasę, w stylu Pager, SorPanel, SearchPanel itp.

Oczywiste jest jednak, że do Pagera może trafić tylko lista, która potrafi być stronnicowana, więc Pager wymaga od otrzymywanego obiektu implementacji interfejsu Pageble.
Tak samo SortPanel itd. Dzięki temu bardzo łatwo, już na poziomie najprostszych testów sprawdzić, czy dana lista została poprawnie obsłużona.
W końcu nie tylko może mieć kilka interfejsów, które wymuszą na niej utworzenie odpowiednich metod, to jeszcze ewentualne błędy zostaną wykazane od razu po pierwszym odpaleniu testu (nie muszę fizycznie kliknąć w żaden link do stronnicowania winksmiley.jpg )


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
vegelus
post 7.01.2008, 02:29:15
Post #26





Grupa: Zarejestrowani
Postów: 25
Pomógł: 0
Dołączył: 31.05.2005

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


Przepraszam, że odgrzewam temat. Chciałbym poruszyć problem związany z interfejsami i myślę, że kontynuacja w tym wątku będzie odpowiednia.
Postanowiłem wykorzystać wzorzec kompozycji do zebrania kilku podobnych elementów, lecz z niewielkimi różnicami. Poniższy kod uprościłem do dwóch różnic. Do plecaka mogę włożyć element będący dzieckiem klasy abstrakcyjnej Item. Ale w zależności od materiału z jakiego jest wykonany dany element implementuje odpowiedni interfejs(szkło i drewno). Poniżej przedstawiam kod oraz proszę o podanie w jaki sposób w klasie Bag rozróżniać z jakiego materiału jest dany element aby wydać odpowiedni dźwięk.

  1. <?php
  2. class ItemExeption extends Exception {}
  3.  
  4. interface szklo{
  5. function brzdek();
  6. }
  7. interface drewno{
  8. function pukpuk();
  9. }
  10.  
  11. abstract class Item {
  12. abstract function weigth();
  13.  
  14. function addItem(Item $item){
  15. throw new ItemExeption(get_class($this)." to liść");
  16. }
  17.  
  18. function removeItem(Item $item){
  19. throw new ItemExeption(get_class($this)." to liść");
  20. }
  21.  
  22. }
  23.  
  24. class butelka extends Item implements szklo {
  25. function weigth(){
  26. return 2;
  27. }
  28.  
  29. function brzdek(){
  30. return 'Brzdek! Brzdek! ';
  31. }
  32. }
  33.  
  34. class patyk extends Item implements drewno {
  35. function weigth(){
  36. return 4;
  37. }
  38.  
  39. function pukpuk(){
  40. return 'Puk! Puk! ';
  41. }
  42. }
  43.  
  44. class drewniane_luterko extends Item implements drewno, szklo {
  45. function weigth(){
  46. return 3;
  47. }
  48. function pukpuk(){
  49. return 'Puk! Puk! ';
  50. }
  51. function brzdek(){
  52. return 'Brzdek! Brzdek! ';
  53. }
  54. }
  55.  
  56. class Bag extends Item {
  57. private $items = array();
  58.  
  59. function addItem(Item $item) {
  60. foreach($this->items as $thisItem){
  61. if($item === $thisItem){
  62. return;
  63. }
  64. }
  65. $this->items[] = $item;
  66. //gdzieś tutaj chciałbym móc użyć czegoś takiego 
  67. if($item == 'szklo'){
  68.  $item->brzdek();
  69. }
  70. function removeItem(Item $item){
  71. $items = array();
  72. foreach($this->items as $thisItem){
  73. if($item !== $thisItem){
  74. $items[] = $thisItem; 
  75. }
  76. }
  77. $this->items = $items;
  78. }
  79. function weigth(){
  80. $ret = 0;
  81. foreach($this->items as $item){
  82. $ret += $item->weigth();
  83. }
  84. return $ret;
  85. }
  86. }
  87.  
  88. $plecak = new Bag();
  89. //wkladamy do plecaka butelke i sluszymy brzdek
  90. $plecak->addItem(new butelka());
  91. //wkladamy patyk i slyszymy pukpuk
  92. $plecak->addItem(new patyk());
  93. //sprawdzamy ciezar wlorzonych przedmiotow
  94. print 'Plecak waży: '. $plecak->weigth() . ' kg.<br>';//wynik: Plecak waży: 6 kg.
  95.  
  96. ?>


Ten post edytował vegelus 7.01.2008, 02:31:09
Go to the top of the page
+Quote Post
mike
post 7.01.2008, 08:33:07
Post #27





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

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


Jest do tego gotowy operator: instanceof
Go to the top of the page
+Quote Post
Virti
post 7.01.2008, 19:11:07
Post #28





Grupa: Zarejestrowani
Postów: 115
Pomógł: 12
Dołączył: 11.01.2005
Skąd: Zduńska Wola

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


A ja, jeśli można, chciałbym prosić o wytłumaczenie jak krowie na granicy po co w ogóle stosuje się klasy abstrakcyjne? Przeczytałem cały temat i niestety nie mogę tego zrozumieć.
Go to the top of the page
+Quote Post
Whisller
post 8.01.2008, 08:04:55
Post #29





Grupa: Zarejestrowani
Postów: 77
Pomógł: 5
Dołączył: 29.03.2006
Skąd: Poznań

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


@Virti
Aby ułatwić sobie implementację smile.gif Mały przykład kodu.
  1. <?php
  2. abstract class HeniuTreeNode 
  3. {
  4. /**
  5.  * Ustawienie ID gałęzi
  6.  *
  7.  * @param int $id
  8.  */
  9. public function setId($id)
  10. {
  11. $this->id = $id;
  12. }
  13. public function getId()
  14. {
  15. return $this->id;
  16. }
  17.  
  18. /**
  19.  * Ustawienie nazwy elementu
  20.  *
  21.  * @param string $name
  22.  */
  23. public function setName($name)
  24. {
  25. $this->name = $name;
  26. }
  27. public function getName()
  28. {
  29. return $this->name;
  30. }
  31.  
  32. private $id = null;
  33. private $name = null;
  34. }
  35. ?>


Oraz klasa dziedzicząca po niej

  1. <?php
  2. class HeniuTreeNodeNested extends HeniuTreeNode
  3. {
  4. // Tutaj cały kod
  5. // Mamy dostęp do metod set/getId oraz set/getName
  6. )
  7. ?>


I teraz wiesz że każda z klas odpowiadających za pojedyńczą gałąź będzie miała takie metody jak set/getId set/getName implementujesz je w klasie abstrakcyjnej po której będą dziedziczyć Twoje klasy i wtedy nie musisz już "przepisywać" ich na nowo (jeśli nie chcesz) w każej klasie z osobna.
Dzięki temu uzysujesz już wstępną implementację, a nic nie stoi na przeszkodzie aby w danej klasie nadpisać(jeśli jest taka potrzeba) te metody(set/getId czy set/getName)
Może to trochę zamotane ale ogólnie rzecz biorąc dużej polityki tutaj nie ma smile.gif


--------------------
Blog | Strona www | wicia.pl
Go to the top of the page
+Quote Post
Virti
post 8.01.2008, 18:35:14
Post #30





Grupa: Zarejestrowani
Postów: 115
Pomógł: 12
Dołączył: 11.01.2005
Skąd: Zduńska Wola

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


Ok, czyli rozumiem, że abstrakcja dostarcza funkcji, które są używane przez kilka(naście) pochodnych klas, tak aby nie trzebabyło w każdej z osobna ich deklarować? W takim razie dlaczego nie stosować normalnych klas (nie-abstrakcyjnych) jako rodziców? Żeby zabezpieczyć się przed wywołaniem bezpośrednio tej funkcji?
Go to the top of the page
+Quote Post
domis86
post 8.01.2008, 19:38:08
Post #31





Grupa: Zarejestrowani
Postów: 255
Pomógł: 5
Dołączył: 20.03.2007
Skąd: Kraków

Ostrzeżenie: (30%)
XX---


@virti: żeby wymusic dziedziczenie po tej klase. Klasa abstrakcyjna to prototyp, szkielet, nie moze byc uzyta bezposrednio.
Go to the top of the page
+Quote Post
Sedziwoj
post 9.01.2008, 11:58:07
Post #32





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


@vegelus
Wyjaśnij mi czym się różni "brzdek"/"pukpuk" od "dzwiek"?


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
Cysiaczek
post 9.01.2008, 12:41:11
Post #33





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Ja się zawsze staram robić klasy abstrakcyjne. Nazwa tego typu klas odzwierciedla to, czym ona jest. Widząc słówko abstract, natychmiast uzyskujemy informacje o tym, że implementacja jest w pochodnych, które tworzą jakąś rodzinę klas wyspecjalizowanych klas. Jak rozejrzymy sie po metodach tej klasy, będziemy wiedzieli, jakie operacje są wspólne, a jakie klasa wymusza w swoich pochodnych.
Stosując zwykła klasę bazową, te informacje będziemy musieli zdobyć sami przeszukując kod podklas.
To jest jedna z cech oop - ułatwienie zrozumienia logiki systemu.

Pozdrawiam.


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
-=Peter=-
post 1.02.2008, 21:28:08
Post #34





Grupa: Zarejestrowani
Postów: 304
Pomógł: 51
Dołączył: 4.02.2005
Skąd: Kraków

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


Witam, może powinienem założyć nowy temat, ale wolę nie zaśmiecać forum smile.gif Napotkałem problem, oto kod który wg mnie powinien działać:

  1. <?php
  2. interface A{}
  3.  
  4. interface B extends A{}
  5.  
  6. interface C{
  7.  public function metoda($obiekt);
  8. }
  9.  
  10. abstract class D implements C{
  11.  public function metoda($obiekt){
  12. //jakas implementacja
  13.  }
  14. }
  15.  
  16. class E extends D{
  17.  public function metoda($obiekt){
  18. parent::metoda($obiekt);
  19.  }
  20. }
  21. ?>


Problem jest taki, że wywala błąd że metoda E::metoda nie jest kompatibilna z interfejsem C::metoda... (Declaration of E::metoda() must be compatible with that of C::metoda()). Tak, jest inne wymuszenie typu w klasie D, ale podany typ jest dziedziczony po interfejsie który jest wymuszony w interfejsie C...

Czyli podsumowywując, jeśli chcemy wymusić typ w interfejsie to już nie da się później w klasach implementujących ten interfejs, w tej metodzie wymusić typ, który dziedziczy po typie wymuszonym pierwotnie w interfejsie? (mam nadzieje, że zrozumiecie o co mi chodzi tongue.gif) Jak w takim razie to "obejść"? Czy może jest to jakiś bug w php5, albo dziwne i świadome ograniczenie? tongue.gif Bo na "chłopski rozum" powinno to działać.

EDIT: pytanie jak to "obejść" raczej jest nie na miejscu, bo wiem jak to obejść, tylko trochę to jest niewygodne tongue.gif

EDIT2: znalazłem już odpowiedź smile.gif wg twórców php, nie jest to błąd. PHP nie sprawdza, czy rzutowany typ jest dziedziczony po tym, który został zrzutowany w interfejsie/klasie po której dana klasa jest dziedziczona. Wg mnie to trochę dziwne, no ale cóż poradzić...

Ten post edytował -=Peter=- 2.02.2008, 12:59:42


--------------------
Go to the top of the page
+Quote Post
Sajrox
post 2.02.2008, 19:36:10
Post #35





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Wracająć do tematu to jak dobrze zrozumialem, interfejsy tylko i wyłacznie wymuszają utworzenie danych metod w klasie która implementuje dany interfejs questionmark.gif
Go to the top of the page
+Quote Post
-=Peter=-
post 2.02.2008, 19:55:00
Post #36





Grupa: Zarejestrowani
Postów: 304
Pomógł: 51
Dołączył: 4.02.2005
Skąd: Kraków

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


Interfejsy nie tylko wymuszają istnienie danych metod, ale także ustalają jaką deklarację ma mieć ta metoda (ile i jakiego typu ma mieć argumenty). W interfejsie możemy tylko wymusić istnienie publicznych metod, jest to z jednej strony logiczne, gdyż interfejs gwarantuje że dana rodzina klas będzie miała ten sam "protokół" do korzystania z nich, a z prywatnych czy chronionych metod nie skorzystamy z poza danej klasy.


--------------------
Go to the top of the page
+Quote Post

2 Stron V  < 1 2
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 Wersja Lo-Fi Aktualny czas: 27.04.2024 - 18:06