Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> OOP. Interfejsy oraz klasy abstrakcyjne, Zabezpieczenie przed programistą?
Jabol
post
Post #1





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

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


Witam,

Nawiązując do http://forum.php.pl/index.php?showtopic=64555&st=80 chciałem troszkę rozjaśnić swoje zdanie na temat obiektowości w programach. Rozumiem koncept OOP i dzielenia aplikacji na obiekty - logiczne, wszystko dzieli się według zastosowania. Ale OOP to nie tylko taki podział. Potem dochodzą do tego interfejsy oraz klasy abstrakcyjne. Rozumiem interfejs, ale czemu interfejs nie może być normalną klasą, przecież i tak nie ma być wykorzystywany w programie? To tak jakby sucha kromka chleba miała być niejadalna, bo jest tylko interfejsem do kromki z serem. A jest jadalna - tylko większość osób kładzie na nią dodatkowo ser czy cośtam. I teraz klasy abstrakcyjne. Rozumiem, że obiekty mają hierarchię, ale po co klasy abstrakcyjne? Jeżeli są to klasy, których nie nalaży używać, to wystarczy ich nie używać - na pewno są przecież bezużyteczne, inaczej nie byłyby abstrakcyjne.

Dlatego mam czasami wrażenie, że OOP to nie tylko standart projektowania, ale również inny troszkę tok myślenia. Rozumiem, że programista musi założyć, że użytkownicy to idioci. Bo oni mogą się nie znać. Ale jeżeli ktoś pisze jakąś obiektową bibliotekę, albo jeszcze gorzej strukturę programu dla siebie, to nie musi wychodzić z założenia, że jest idiotą. Jeżeli programista jest idiotą to jego sprawa, bo jego program i tak nie będzie działał - nie potrzeba do tego warningów/errorów kompilatora/interpretera. Tak samo metody prywatne. Jeżeli w dokumentacji będzie wspomniane nie używać, to mądry programista ich i tak nie użyje, a sprytny użyje i też będzie ok.

Dlatego nie rozumiem, po co w OOP ten cały mechanizm zabezpieczania programów przed... programistami, którzy je piszą?

Pozdrawiam
Go to the top of the page
+Quote Post
2 Stron V   1 2 >  
Start new topic
Odpowiedzi (1 - 35)
Athlan
post
Post #2





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


Moim zdaniem źle podszedłeś do sprawy. Zły przykład i nietrafne argumenty.

Jak już się przyczepiłeś tej kromki chleba... z czego ona powstała? Ze zboża, czy zbożem się najesz? nie, kromka chleba, bułka, rogalik itp dziedziczą po zbożu, który jest odpowiednio obrabiany. Załóż, że zboże to pewnien standard produkcji pieczywa, nie wyprodukujesz go z plastku. Teraz przykład w php.

Mamy abstrakcyjny kontroler z pewnymi metodami, np api __get(), __set(), itp. Wśród nich jest także metoda index() uwględniona w interfejsie, jaki ten abstrakcyjny obiet implementuje. Index to swego rodzaju przymus (standard pieczywa) działania kontorlera, gdyż bez niego (w wypatku braku akcji) zostanie on ewentualnie odpalony. Czym jest dla porównania metoda abstrakcyjna? Może w niej zostać zaprojektowane zupełnie co innego dla dziecka niż dla rodzica, z tym że dziecko potrzebuje metody rodzica. Przykład? obróbka danych:

  1. <?php
  2.  
  3. interface ObrabiarkaTablic
  4. {
  5. function obrobka($aTablica);
  6. }
  7.  
  8. class Rodzic
  9. {
  10. abstract function obrobka($aTablica)
  11. {
  12. // wykonanie jakis operacji
  13. return $aTablica;
  14. }
  15. }
  16.  
  17. class Dziecko extends Rodzic implements ObrabiarkaTablic
  18. {
  19. public function obrobka($aTablica)
  20. {
  21. // poprzednia filtracja danych:
  22. $aTablica = parent::obrobka($aTablica);
  23. // inna przerobka danych
  24. }
  25.  
  26. ?>
Go to the top of the page
+Quote Post
LBO
post
Post #3





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

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


Cytat(Jabol @ 3.04.2007, 19:03:01 ) *
Rozumiem interfejs, ale czemu interfejs nie może być normalną klasą, przecież i tak nie ma być wykorzystywany w programie? To tak jakby sucha kromka chleba miała być niejadalna, bo jest tylko interfejsem do kromki z serem. A jest jadalna - tylko większość osób kładzie na nią dodatkowo ser czy cośtam. I teraz klasy abstrakcyjne. Rozumiem, że obiekty mają hierarchię, ale po co klasy abstrakcyjne? Jeżeli są to klasy, których nie nalaży używać, to wystarczy ich nie używać - na pewno są przecież bezużyteczne, inaczej nie byłyby abstrakcyjne.


To są mechanizmy języka. Skoro powstało pojęcie klasy abstrakcyjnej, to dla mnie jak najbardziej w porządku jest włączenie tego do języka (czyli wyskakujące błędy, gdy taki obiekt stworzę).

Cytat(Jabol @ 3.04.2007, 19:03:01 ) *
Dlatego mam czasami wrażenie, że OOP to nie tylko standart projektowania, ale również inny troszkę tok myślenia. Rozumiem, że programista musi założyć, że użytkownicy to idioci. Bo oni mogą się nie znać. Ale jeżeli ktoś pisze jakąś obiektową bibliotekę, albo jeszcze gorzej strukturę programu dla siebie, to nie musi wychodzić z założenia, że jest idiotą. Jeżeli programista jest idiotą to jego sprawa, bo jego program i tak nie będzie działał - nie potrzeba do tego warningów/errorów kompilatora/interpretera.


Zapewne nigdy nie rozwijałeś kodu po innym programiście, albo nie wracałeś do swojego projektu po długiej przerwie. Spróbuj kiedyś.

Cytat(Jabol @ 3.04.2007, 19:03:01 ) *
Tak samo metody prywatne. Jeżeli w dokumentacji będzie wspomniane nie używać, to mądry programista ich i tak nie użyje, a sprytny użyje i też będzie ok.


Widzisz, naprawdę tu powinno sie przytoczyć jakieś cytaty z mądrych książek i najlepiej kilka real life examples. Istnieją metody prywatne i metody publiczne, do jednych jest dostęp z zewnątrz obiektu, do innych nie ma - koniec i kropka. Jeżeli uzywam tego przy programowaniu, używam tego nie bez kozery.

Cytat(Jabol @ 3.04.2007, 19:03:01 ) *
Dlatego nie rozumiem, po co w OOP ten cały mechanizm zabezpieczania programów przed... programistami, którzy je piszą?


Sam sobie odpowiedziałeś, to zabezpiecza programistę - sprawia, że mozliwości popełnienia błędu maleją.

Cytat(Jabol @ 3.04.2007, 19:03:01 ) *
Pozdrawiam


No, cześć, cześć smilingsmiley.gif

Ten post edytował LBO 3.04.2007, 18:32:29
Go to the top of the page
+Quote Post
Jabol
post
Post #4





Grupa: Przyjaciele php.pl
Postów: 1 467
Pomógł: 13
Dołączył: 22.02.2003

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


Dzieki za wyjaśnienie, rozumiem w czym rzecz.

Czyli jak widzę OOP to rzeczywiście bardziej dziecko inżynieri programowania niż np. algorytmiki. Może dlatego nie całkiem mogę to pojąć, choć widzę zalety.

Pozdrawiam
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #5





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

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


Tylko w opisie pojawił się pewien bug, bo bułki/chleb agregują zboże (czy raczej pieczywo to robi, i dodatkowo inne składniki), a nie dziedziczą... a bułki i chlew dziedziczą po pieczywo (mniej więcej, zleży jak to dokładnie rozpisywać)
Go to the top of the page
+Quote Post
Athlan
post
Post #6





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


Cytat
Tylko w opisie pojawił się pewien bug, bo bułki/chleb agregują zboże (czy raczej pieczywo to robi, i dodatkowo inne składniki), a nie dziedziczą... a bułki i chlew dziedziczą po pieczywo (mniej więcej, zleży jak to dokładnie rozpisywać)


To już bardziej dziedziczenie wielopoziomowe, nie chciałem tutaj wprowadzać kogoś w obszar głębszego rozmyślania, tylko podac jakis przykład, ale słuszna uwaga (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Cytat
Czyli jak widzę OOP to rzeczywiście bardziej dziecko inżynieri programowania niż np. algorytmiki. Może dlatego nie całkiem mogę to pojąć, choć widzę zalety.


Z czasem, jak nabierzesz więcej doświadczenia, będziesz całował interfejsy i abstrakty po nogach - gwarantuję. Teraz póki co dostałeś suche przykłady, postaraj się je wykorzysać we wzorcach projektowych, zobaczysz, że naprawdę się przydają i coś z tego de facto jest.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #7





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

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


To w sumie pokazuje jeszcze jedno, gdyż pieczywo jest interfejsem (lub abstrakcją, zależy jak zdefiniujemy) to chyba logiczne jest, że nie można tworzyć obiektu tego typu, bo takie coś nie może istnieć, dlatego kompilator/interpreter powinien wyrzucić błąd.
Go to the top of the page
+Quote Post
Zeman
post
Post #8





Grupa: Zarejestrowani
Postów: 70
Pomógł: 0
Dołączył: 29.03.2007

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


Ja się jeszcze dorzucę.

Interfejsy w językach skryptowych odgrywają trochę inną rolę niż w językach kompilowanych.

Interfejsy w językach kompilowanych:
W językach kompilowanych interfejs daje możliwość symulowania dziedziczenia wielobazowego przy językach, które jako takiego dziedziczenia wielobazowego klas nie mają. Poza tym, interfejsy narzucają specyfikację i jakby karzą bezwzględnie tej specyfikacji się trzymać, znaczy się dla autorów klas które będą implementować dany interfejs. Następną i chyba główną cechą interfejsów w językach kompilowanych jest możliwość sterowania obiektem zdalnie, znaczy się jedna aplikacja może sterować obiektem który istnieje w innej aplikacji (programowanie rozproszone).


W językach skryptowych:
Tutaj interfejs jakby traci swoją moc dawania możliwości symulowania dziedziczenia wielobazowego, ponieważ język skryptowy metody wywołuje i tak po nazwach (tzw. późne wiązania). Narzucanie pewnej specyfikacji pozostaje tj dla języków kompilowalnych, natomiast jeśli chodzi o programowanie rozproszone to szczerze mówiąc nie wiem jak to jest w PHP, nic mi nie wiadomo żeby interfejsy w tym pomagały, zresztą cieżko mi sobie wyobrazić programowanie rozproszone w PHP (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) No, chyba że tylko jako aplikacja kliencka.


Pozwiodronka,
Zeman.


Aha, co do klas abstrakcyjnych, to jest takie narzucanie pewnej specyfikacji autorom klas chcącym dziedziczyć po danej klasie abstrakcyjnej.

Co do metod prywatnych (private), chronionych (protected) i publicznych (public), to jest to swego rodzaju umożliwienie pisania metod na wewnętrzny użytek klasy i eśli ktoś chciałby dziedziczyć po klasie i używać tych metod, to już nie może, wtedy metoda musi być conajmniej protected. Prosze mi uwierzyć że chowanie metod ma sens - niekiedy metoda niespecjalnie się nadaje do użytku z zewnątrz, a programista nie będący autorem danej klasy może popsuć skrypt jak jej nieumiejętnie użyje. Poza tym, utrzymuje porządek, nie kusi żeby kombinować (choć może i bardziej kusić).

Osobiście w PHP zwykłem często używać private, protected i public dla metod i pól, oraz często static. Interfejsów w PHP osobiście nie używam, ale w Delphi niemalże wszędzie.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #9





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

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


Cytat(Zeman @ 3.04.2007, 20:58:25 ) *
....
Co do metod prywatnych (private), chronionych (protected) i publicznych (public), to jest to swego rodzaju umożliwienie pisania metod na wewnętrzny użytek klasy i eśli ktoś chciałby dziedziczyć po klasie i używać tych metod, to już nie może, wtedy metoda musi być conajmniej protected.

Chyba coś Ci się pomieszało, bo protected nie pozwala na uruchomienie metody z zewnątrz ale jest dziedziczone, aby nie można było dziedziczyć to private aby nie można było nadpisać final.
Go to the top of the page
+Quote Post
Zeman
post
Post #10





Grupa: Zarejestrowani
Postów: 70
Pomógł: 0
Dołączył: 29.03.2007

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


Cytat(Sedziwoj @ 3.04.2007, 21:06:40 ) *
Chyba coś Ci się pomieszało, bo protected nie pozwala na uruchomienie metody z zewnątrz ale jest dziedziczone, aby nie można było dziedziczyć to private aby nie można było nadpisać final.


Nie nie pomieszało mi się nic, bo napisałem jeśli ktoś chciałby dziedziczyć po klasie i używać jej metod, może tylko dla jasności nie dopisałem że w klasie dziedziczonej.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #11





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

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


Ale przy protected w klasie dziedziczącej jest widoczna, właśnie po to się ustawia tą widoczność aby nie można było jej z zewnątrz wywołać, ale w klasie dziedziczącej jak najbardziej.
Zacytuję, bo chyba tego nie widzisz:
Cytat
i eśli ktoś chciałby dziedziczyć po klasie i używać tych metod, to już nie może, wtedy metoda musi być conajmniej protected.

wtedy musi być private
Go to the top of the page
+Quote Post
Zeman
post
Post #12





Grupa: Zarejestrowani
Postów: 70
Pomógł: 0
Dołączył: 29.03.2007

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


Cytat(Sedziwoj @ 3.04.2007, 21:25:43 ) *
Ale przy protected w klasie dziedziczącej jest widoczna, właśnie po to się ustawia tą widoczność aby nie można było jej z zewnątrz wywołać, ale w klasie dziedziczącej jak najbardziej.
Zacytuję, bo chyba tego nie widzisz:

wtedy musi być private


No to sie chyba faktycznie nie rozumiemy, bo poprawiasz mnie tak samo ja ja piszę.
Podsumowywując krótko i jednoznacznie:
private - metoda widoczna tylko w klasie w ktorej jest definicja tej metody, niewidoczna w klasach potomnych ani poza klasą
protected - tj private a dodatkowo widoczna w klasach potomnych
public - tj protected a dodatkowo poza klasą
Go to the top of the page
+Quote Post
mike
post
Post #13





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

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


Cytat(Zeman @ 3.04.2007, 21:33:24 ) *
private - metoda widoczna tylko w klasie w której jest definicja tej metody, niewidoczna w klasach potomnych ani poza klasą
protected - tj private a dodatkowo widoczna w klasach potomnych
public - tj protected a dodatkowo poza klasą
Dziwisz się później, że nikt Cię nie rozumie. Napisz to jak po ludzku a nie się bawisz (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
Jak protected to protected a nie jakieś "ale".

private - składowe klasy (pola, funkcje) widoczne (czyli dostęp do niech) tylko i wyłącznie wewnątrz klasy;
protected - składowe klasy, do których dostęp jest z wewnątrz klasy oraz wewnątrz klas dziedziczących.
public - składowe klasy do których dostęp można uzyskać w dowolnym miejscu aplikacji.

Ten post edytował mike_mech 3.04.2007, 21:19:43
Go to the top of the page
+Quote Post
Turgon
post
Post #14





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

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


W mojej skromnej opinii, klasy abstrakcyjne, finale i interfejsy, to błogosławieństwo. Wiem to z doświadczenia, bo kod którego używam rozwijałem przez ponad rok w różnych odstępach czasu. Z dużą ilość modyfikacji, różnymi stylami programowania, ale zgodnie z OOP i teraz poprawia oraz używa się to cudownie.

Specjalnie dla niedomyślnego pana Athlana uzasadnienie:
Mam ok. 50 klas, które były pisane na przestrzeni 1 roku i gdyby nie jasno zdefiniowane interfejsy itp. , miałbym spore problemy, z powrotem do programowania, po przerwie jaką sobie ostatnio zrobiłem (2 miesiące).

Ten post edytował Turgon 4.04.2007, 18:22:43
Go to the top of the page
+Quote Post
enigma
post
Post #15





Grupa: Zarejestrowani
Postów: 163
Pomógł: 0
Dołączył: 10.09.2006

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


Cytat(Athlan @ 3.04.2007, 19:26:15 ) *
  1. <?php
  2.  
  3. interface ObrabiarkaTablic
  4. {
  5. function obrobka($aTablica);
  6. }
  7.  
  8. class Rodzic
  9. {
  10. abstract function obrobka($aTablica)
  11. {
  12. // wykonanie jakis operacji
  13. return $aTablica;
  14. }
  15. }
  16.  
  17. class Dziecko extends Rodzic implements ObrabiarkaTablic
  18. {
  19. public function obrobka($aTablica)
  20. {
  21. // poprzednia filtracja danych:
  22. $aTablica = parent::obrobka($aTablica);
  23. // inna przerobka danych
  24. }
  25.  
  26. ?>

dołączę się do tematu (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) klasa Rodzic musi być abstrakcyjna chyba, tak (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)

kurde czegoś tu nie rozumiem, no po co tak robić
class Dziecko extends Rodzic implements ObrabiarkaTablic
nie można by tylko
class Dziecko extends Rodzic
bo jakoś oprócz tego że wymuszają w klasie która dziedziczy zaimplementowanie odpowiednch funkcji nie widzę idei (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) proszę o jaśniejsze wytłumaczenie po co to używamy

Ten post edytował enigma 1.05.2007, 16:47:54
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #16





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

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


Cytat
kurde czegoś tu nie rozumiem, no po co tak robić
class Dziecko extends Rodzic implements ObrabiarkaTablic
nie można by tylko
class Dziecko extends Rodzic
bo jakoś oprócz tego że wymuszają w klasie która dziedziczy zaimplementowanie odpowiednch funkcji nie widzę idei proszę o jaśniejsze wytłumaczenie po co to używamy

Interfejsy zostaly wziete z Javy, gdzie zmienna musi miec typ:
Kod
ObrabiarkaTablic ot = new Dziecko(); // jako ze dziecko implementuje ObrabiarkaTablic wiec jest typu ObrabiarkaTablic
ot = new XXXXXXX(); // gdzie XXXX..XX tez implemetuje ObrabiarkaTablic

a to wszystko po to zeby mozna bylo wykonac
Kod
ot.obrobka( tablica )

bo kompilator musi wiedziec czy na obiekcie 'ot mozna wywolac obrobka().

W PHP nie ma typowania zmiennych i mamy duck-typing, tzn. jesli na obiekcie wywolamy metode a on ja posiada to jest OK, czyli -> interfejsy sa niepotrzebne od strony wykonania, 'kompilacji' a bardziej do dokumentacji kodu, ogarniecia jego struktury
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #17





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

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


Tu po prostu Rodzic powinien implementować ObrabiarkaTablic, a wtedy nie trzeba dzieciom tego pisać, bo to jest z rodzica (jeśli się nie mylę przy takiej składni w Java też by nie było problemu)
A dodanie interfejsu to raczej kiedy rozszerzany jest rodzica, np. amfibia dziedziczy po samochodach, ale też implementuje łodzie, bo może pływać (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)
Go to the top of the page
+Quote Post
enigma
post
Post #18





Grupa: Zarejestrowani
Postów: 163
Pomógł: 0
Dołączył: 10.09.2006

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


Cytat(dr_bonzo @ 1.05.2007, 20:03:22 ) *
czyli -> interfejsy sa niepotrzebne od strony wykonania, 'kompilacji' a bardziej do dokumentacji kodu, ogarniecia jego struktury
czyli przy każtym projekcie robić sobie klasy abstrakcyjne i interfejsy (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)


Cytat(Sedziwoj @ 2.05.2007, 12:30:45 ) *
A dodanie interfejsu to raczej kiedy rozszerzany jest rodzica, np. amfibia dziedziczy po samochodach, ale też implementuje łodzie, bo może pływać (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)
czyli wielodziedziczenie

oprócz tych dwóch, są jeszcze jakieś zastosowania ?

--EDIT
przeczytałem wszystkie topiki na forum o interfejsach i klasach abstrakcyjnych ale jeszcze czegoś mi brakuje (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) musze się z tym przespać (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

w jednej ksiżące znalazłem fajny przykład dla kals abstrakcyjnych
mamy klasę ssak no co to jest, nic konkretnego, nie można mieć obirektu klasy ssak, to byłoby bez sensu, więc robimy abstrakcję i dziedziczymy po niej (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
chyba dobre (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) jeszcze żeby tak ładnie były interfejsy wytłumaczone (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)

Ten post edytował enigma 2.05.2007, 14:15:09
Go to the top of the page
+Quote Post
menic
post
Post #19





Grupa: Zarejestrowani
Postów: 493
Pomógł: 0
Dołączył: 14.06.2003
Skąd: Tomaszów Lubelski/Rzeszów

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


Ale interfejsy sa bardzo proste do zrozumienia. Stosuje sie je najczęściej kiedy jakaś klasa moze byc wymieniona na inna. Np. handler sesji, Router. Wtedy w interefejsie zawierasz które metody są wymagane do poprawnego działania nowej klasy z pozostałymi i jazda (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

A co do przykladów... Ja nie wiem po co ludzie w tych wszstkich książkach dają te durne odniesienia do samochodów, zwierząt. Jak czytałem ksiązki to nigdy tego nie mogłem poją. Dopiero jak pracowałem z kodem to wszystko sie wyjasniło. Takie przykłady wprowadzają tylko bezsensowne zamieszanie.

Ten post edytował menic 13.05.2007, 10:14:31
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #20





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




Interfejsy to dla mnie głównie nowe typy, które można wymusić.
Proszę pominąć niedociągnięcia w implementacji

  1. <?php
  2. interface inteligencjaNaPewenymPoziomie{}
  3. abstract class Ssaki{}
  4.  
  5. class Czlowiek extends Ssaki implements inteligencjaNaPewenymPoziomie{}
  6. class Orangutan extends Ssaki{}
  7.  
  8. // 2 podobne, ale jakże różne klasy Budowniczy
  9.  
  10. class Budowniczy{
  11.  
  12. function budujSamolot(Ssaki $object){}
  13. function budujSamolot(Ssaki $object); //orangutan z powodzeniem wybuduje na samolot : )
  14. function malujWPaincie(Ssaki $object){} // orangutan i czlowiek mogą używać Painta(TM)
  15. }
  16.  
  17.  
  18. class Budowniczy{
  19.  
  20. function __construct(Ssaki $object){}
  21. function budujSamolot(inteligencjaNaPewenymPoziomie $object){} // tutaj tylko obiekt typu inteligencjaNaPewenymPoziomie bedzie mógł wykonać zadanie
  22. function malujWPaincie(Ssaki $object){} // orangutan zawsze może pomalować : P
  23. }
  24. ?>


Pozdrawiam.

Ten post edytował Cysiaczek 13.05.2007, 11:59:59
Go to the top of the page
+Quote Post
Sedziwoj
post
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.
Go to the top of the page
+Quote Post
Turgon
post
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 (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
splatch
post
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. ?>
Go to the top of the page
+Quote Post
LBO
post
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
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 (IMG:http://forum.php.pl/style_emoticons/default/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 (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) )
Go to the top of the page
+Quote Post
vegelus
post
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
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
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
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ę (IMG:http://forum.php.pl/style_emoticons/default/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 (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
Virti
post
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
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
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"?
Go to the top of the page
+Quote Post
Cysiaczek
post
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.
Go to the top of the page
+Quote Post
-=Peter=-
post
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 (IMG:http://forum.php.pl/style_emoticons/default/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 (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) ) Jak w takim razie to "obejść"? Czy może jest to jakiś bug w php5, albo dziwne i świadome ograniczenie? (IMG:http://forum.php.pl/style_emoticons/default/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 (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)

EDIT2: znalazłem już odpowiedź (IMG:http://forum.php.pl/style_emoticons/default/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
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 (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)
Go to the top of the page
+Quote Post
-=Peter=-
post
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
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.12.2025 - 20:39