Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Obiektowość w PHP5
Forum PHP.pl > Forum > PHP > Object-oriented programming
Jarod
Właśnie czytam sobie wprowadzenie do programowania obiektowego z ksiażki (PHP5 zaawansowane programowanie). Wiem jak tworzyć klasę, rozumiem hermetyzację (właściwośći public, private i protected), dziedziczenie nawet załapałem. Rozumiem zachowywanie właściwości przodka przez stosowanie parent::[nazwaFunkcji] itp.

Ale mam dwa pytania:

1. Domyślnie funkcje, tzn metody są domyślnie public. To, że właściwości mogą być np private jest dla mnie zrozumiałe. Ale czy jest sens tworzyć metodę private? Po co?

2. Nie mogę zrozumieć sensu istnienia interfejsu. Może w tej książce jest to beznadziejnie opisane ale sami zobaczcie. Autor pisze:

Cytat
(...)Mając uzgodniony zestaw metod, możemy sprawić, by zupełnie różne obiekty były przekazywane do tych samych funkcji bez potrzeby tworzenia między nimi relacji opartych na dziedziczeniu.(...)

i podaje taki przykład:

Plik interface.Openable.php
  1. <?php
  2. interface Openable {
  3. abstract function open();
  4. abstract function close();
  5. }
  6. ?>



Plik class.Door.php
  1. <?php
  2. require_once ('interface.Openable.php');
  3.  
  4. class Door implements Openable {
  5.  
  6. private $_locked = false;
  7.  
  8. public function open() {
  9. ...
  10. ...
  11. }
  12. public function close() {
  13. ..
  14. ...
  15. }
  16. public function lockDoor() {
  17. ...
  18. ...
  19. }
  20. public function unlockDoor() {
  21. ...
  22. ...
  23. }
  24. }
  25. ?>



Plik class.Jar.php
  1. <?php
  2. require_once ('interface.Openable.php');
  3.  
  4. class Jar implements Openable {
  5.  
  6. private $contents;
  7.  
  8. public function __construct($contents) {
  9.  
  10. $this->contents = $contents;
  11. }
  12. public function open() {
  13. ...
  14. ...
  15. }
  16. public function close() {
  17. ..
  18. ...
  19. }
  20. ?>


i wreszcie plik główny
testOpenable.php
  1. <?php
  2. require_once ('class.Door.php');
  3. require_once ('class.Jar.php');
  4.  
  5. function openSomething(Openable $obj)
  6.  {
  7. $obj -> open();
  8. }
  9.  
  10. $objDoor = new Door();
  11. $objJar = new Jar('galaretka');
  12.  
  13. openSomething($objDoor);
  14. openSomething($objJar);
  15. ?>



A następnie autor pisze:
Cytat
(...)Ponieważ zarówno klasa Door, jak i Jar implementują interfejs Openable, można przesłać obiekty każdej z tych klas do funkcji openSomething(). Ponieważ funcja ta akceptuje tylko coś, co implementuje interfejs Openable, wiemy, że możemy w jej ramach wywołać funkcję open() i close(). Nie należy jednak próbować dostępu do właściwości contents ani używać funkcji lock() lub unlock() z poziomu aplikacji funkcji openSomething(), ponieważ ta właściwość i te moetody nie są częścią interfejsu. (...)


Skoro możemy używać tylko tych metod, które zostały wymienione w interfejsie to po jakiego grzyba w klasach tworzył inne metody? Po co wogóle ten interfejs skor i tak powtarzamy kod. W klasie Door piszemy metodę open() i close() i w klasie Jar też piszemy. A w obiektowości chodzi m.in. o nie powielanie kodu (słowa autora).

Próbuje zrozumieć ten przykład, żeby nie mieć dalej problemów w następnych rozdziałąch, ale wydaje mi się to bez sensu.
Może mi to ktoś wytłumaczyć?
Ludvik
Cytat
1. Domyślnie funkcje, tzn metody są domyślnie public. To, że właściwości mogą być np private jest dla mnie zrozumiałe. Ale czy jest sens tworzyć metodę private? Po co?

Czasami zdarzają się takie przypadki, gdzie w wielu publicznych metodach powtarza się ten sam kod. Wtedy możesz jednkrotnie napisać go w metodzie prywatnej i wywoływać ją z odpowiednich miejsc. Zmniejsza się ilość kodu podatnego na błędy... Prywatna po to, aby nikt nie odwołał się do metody, która nie ma nic wspólnego z prawdziwym interfejsem obiektu.

2. [...]
Interfejs mówi, które metody dana klasa musi udostępniać, a nie o całym interfejsie danej klasy. Znając intefejs klasy możemy być pewni, co ona potrafi zrobić. Nie wiemy natomiast, czy nie potrafi czegoś jeszcze... Tak to już bywa, że niektóre klasy są zgodne z interfejsem, lecz udostępniają jeszcze coś specjalnego. Dlatego właśnie autor dopisał te metody.
Ja_Szczur
1) głupi przykład, ale:
  1. <?php
  2. class engine
  3. {
  4.  //...
  5.  
  6.  private function deleteAll()
  7.  {
  8. // ...
  9.  }
  10. }
  11.  
  12. $e = new Engine;
  13. $e->load();
  14. $e->run();
  15.  
  16. // ale ze mnie żartowniś!
  17. $e->deleteAll();
  18. ?>


2) pomyśl o tym inaczej:
masz różne klasy, które reprezentują [implementują] marki samochodów [samochód - interfejs]
wymagasz od nich, żeby mogły jechać, otwierać drzwi, mieć klimatyzajcę itd. tongue.gif [metody wymagane w interfejsie]
chcesz pojechać samochodem: wybierając którąkolwiek klasę [mercedes, bmw, fiat] implementującą interfejs samochód, masz pewność, że jest tam metoda go() czy też run() - nie martwisz się o to!

czyli: masz kilka samochodów, jedne z klimatyzacją, inne z barkiem na pokładzie
ale wiesz jedno: wszystkie mają metody run() openDoors() i np. szlagTrafilSilnik() biggrin.gif

jeżleli za ciemno wyjaśniłem, daj znać, rzucę przykład na systemie newsów w cms'ie czy coś :]
mike
Przenoszę z Przedszkola na php :: PHP5
nazihipi
Cytat
1. Domyślnie funkcje, tzn metody są domyślnie public. To, że właściwości mogą być np private jest dla mnie zrozumiałe. Ale czy jest sens tworzyć metodę private? Po co?


1. po to abyś nie miał do niej dostępu z zewnątrz
2. aby nie została odziedziczona

Cytat
Czasami zdarzają się takie przypadki, gdzie w wielu publicznych metodach powtarza się ten sam kod. Wtedy możesz jednkrotnie napisać go w metodzie prywatnej i wywoływać ją z odpowiednich miejsc. Zmniejsza się ilość kodu podatnego na błędy...

do tego wcale nie potrzeba prywatnej metody...
Ludvik
No oczywiście, że nie potrzeba prywatnej metody. Najlepiej, kiedy ktoś sobie z zewnątrz wywoła metodę, która namiesza wewnątrz klasy... A jak ją odziedziczy, to też fajnie jest smile.gif
nazihipi
oczywiście, logiczna sprawą jest, że chroniony kod umieszcze się w metodach prywatnych...

z twojej wypowiedzi jednak można zrozumieć, że "powtarzający się kod w metodach publicznych możemy sobie przenieść do metod prywatnych, bo będzie szybciej." cool.gif

dopiero tu jest sens
Cytat
Prywatna po to, aby nikt nie odwołał się do metody


nie ważne winksmiley.jpg pozdrawiam
TomASS
Co do interfejsów, to dodam jeszcze swoje trzy grosze.

W php (niestety) obiekt nie może dziedziczyć po kilku rodzicach (jak ma to miejsce np. w C++) - może dziedziczyć (jak narazie) tylko po jednym rodzicu. Jest jeden myk - można właśnie do tego używać interfejsów. Obiekt może posiadać wiele interfejsów.

Masz np. interfejs do budynków, który mówi, że klasa z interfejsem budynek musi zawierać metody buduj() oraz zburz(), dodatkow masz interfejs np. supermarket - klasa musi zawierać metody otworz() zamknij i teraz masz np. właśnie supermarket do którego możesz podłączyć interfejs budyku i supermarketu.

smile.gif Chyba nie zamieszałem za bardzo smile.gif
NuLL
Cytat
Nie mogę zrozumieć sensu istnienia interfejsu. Może w tej książce jest to beznadziejnie opisane ale sami zobaczcie. Autor pisze:

Hardcorowa ta ksiazka - albo tlumacz nie mial pojecia o programowaniu albo autor sie zakrecil winksmiley.jpg

Interfejs pozwala wymusic na obiekcie posiadanie okreslonych metod - przydaje sie to np przy pisaniu sterownikow - zakladasz ze klasa musi implementowac interfejs IDriver ktory posiada okreslone metody aby dana klasa mogla byc sterownikiem smile.gif Tam gdzie musisz sobie stworzyc sterownik ( np. w glownej klasie DB aby mozna bylo obluzyc MySQLa i PostgreSQLa ) sprawdzasz czy posiada ona okreslone metody - a robisz to sprawdzajac czy implementuje danych interfejs dzieki f-cji class_implements" title="Zobacz w manualu php" target="_manual Rkingsmiley.png

Cytat
W php (niestety) obiekt nie może dziedziczyć po kilku rodzicach (jak ma to miejsce np. w C++) - może dziedziczyć (jak narazie) tylko po jednym rodzicu. Jest jeden myk - można właśnie do tego używać interfejsów. Obiekt może posiadać wiele interfejsów.Masz np. interfejs do budynków, który mówi, że klasa z interfejsem budynek musi zawierać metody buduj() oraz zburz(), dodatkow masz interfejs np. supermarket - klasa musi zawierać metody otworz() zamknij i teraz masz np. właśnie supermarket do którego możesz podłączyć interfejs budyku i supermarketu.

Implementowanie wielu interfejsow nie ma nic wspolnego z wielodziedziczwniem. Implementowanie wielu interfejsow i tak wymaga napisania calego kodu - wiec co ma piernik do wiatraka questionmark.gif Dziedzicznie pozwala m.in uniknac nadmiaru kodu - a ja tu niczego takiego nie widze tongue.gif
nazihipi
Cytat
Implementowanie wielu interfejsow nie ma nic wspolnego z wielodziedziczwniem. Implementowanie wielu interfejsow i tak wymaga napisania calego kodu - wiec co ma piernik do wiatraka questionmark.gif Dziedzicznie pozwala m.in uniknac nadmiaru kodu - a ja tu niczego takiego nie widze

w pewnym sensie interfejsy można potraktować jako zastępnik wielodziedziczenia;
istnieje także inna właściwość dziedziczenia (nie tylko optymalizacja) mianowicie to, że wiesz do jakich metod klasa dziedzicząca ma dostęp; w tym przykładzie zadanie to spełniają interfejsy
Athlan
Cytat
Masz np. interfejs do budynków, który mówi, że klasa z interfejsem budynek musi zawierać metody buduj() oraz zburz(), dodatkow masz interfejs np. supermarket - klasa musi zawierać metody otworz() zamknij i teraz masz np. właśnie supermarket do którego możesz podłączyć interfejs budyku i supermarketu.


wszyscy nawiązują do świata realnego, a podajcie przykłady odnośnie zastosowania tego w CMS'ie, albo frameworku, bo ci którzy wiedzą o co biega nie maja problemu zrozumieć... przecież uzywali tego już w kodzie, ale jak tego użyć, do czego to właściwie może się przydać to już nikt nie pisze... w żadnej książce i w żadnym artykule o OOP

pozdrawiam smile.gif

p.s. proszę wziąźć sobię tą uwagę do serca (mówie do tych którzy radzą, ale niejaśnie jak im się zdaje smile.gif )
Ludvik
Tworzysz kontener dla danych, który możesz zserializować, odwoływać się do niego jak do tablicy oraz iterować go. Musisz zaimplementować interfejsy Serializable, ArrayAccess (nie pamiętam czy tylko ten do tablicy...) oraz Iterator.

Tworzysz system newsów z jednolitym cache udostępnianym dla każdego obiektu. Każdy news musi implementować i interfejs newsa i Cache...

Przykładów można dużo znaleźć, chociaż nie wszystko jest do końca poprawne (przykład newsów) z założeniami OOP. Jedna klasa = jedna odpowiedzialność. Tutaj tak nie jest. Ale zdarzają się miejsca, w których interfejsy zostają rozdrobnione i po złączeniu ich dostajemy obiekt, który wciąż jest odpowiedzialny tylko za jedno.
TomASS
Cytat
Implementowanie wielu interfejsow nie ma nic wspolnego z wielodziedziczwniem. Implementowanie wielu interfejsow i tak wymaga napisania calego kodu - wiec co ma piernik do wiatraka questionmark.gif Dziedzicznie pozwala m.in uniknac nadmiaru kodu - a ja tu niczego takiego nie widze tongue.gif


Dobrze wiesz, że nie o to mi chodziło tongue.gif Oczywiście, że implementowanie wielu interfejsów wymaga napisania całego kodu, ale przecierz to nie jedyny sens dziedziczenia. Jeśli chcesz aby określona klasa zawierała określone metody w celu współgrania z innymi częściami systemu, musisz to jej jakoś narzucicić. Dla mnie dziedziczenie po dwóch rodzicach można rozwiązać tylko poprzez interfejsy - chociaż zaznaczam, że to takie "para dziedziczenie".

Cytat
w pewnym sensie interfejsy można potraktować jako zastępnik wielodziedziczenia;
istnieje także inna właściwość dziedziczenia (nie tylko optymalizacja) mianowicie to, że wiesz do jakich metod klasa dziedzicząca ma dostęp; w tym przykładzie zadanie to spełniają interfejsy

Dokładnie

Chociaż drogi Nullu zgadzam się z Tobą w 99% tongue.gif
athabus
Ja tu jeszcze dodam 3 grosze... W php5 dodano opcję, dzięki której można wymagać aby zmienna przekazywana do metody miała określony typ. Typem może być również interfejs - czyli dajmy na to projektujemy stronę. Strona może wyświetlać różne rzeczy - np. nowości, artykuły, ostrzeżenia dla użytkowników itp.

Załóżmy, że masz obiekt strona, który posiada funkcję display() odpowiedzialną za wyświetlenie czegoś. Aby uniknąć jakiegoś błędu typu próba wyświetlenia czegoś co nie powinno być wyświetlane, możesz w funkcji display ograniczyc parametry tylko do obiektow inmplementujących określony interfejs, np. Idisplayable.

Ciekawym zastosowaniem interfejsów jest również wzorzec obserwatora. W podanym linku użytko akurat klas Observer i Observable - ale z powodzeniem można je zastąpić interfejsami.
Jarod
Cytat(Ludvik @ 31.07.2006, 21:56 ) *

Czasami zdarzają się takie przypadki, gdzie w wielu publicznych metodach powtarza się ten sam kod. Wtedy możesz jednkrotnie napisać go w metodzie prywatnej i wywoływać ją z odpowiednich miejsc.


Metody publiczne też możesz wywoływać z odpowiednich miejsc. To Ty piszesz kod, więc wiesz co robisz..
Cytat(Ludvik @ 31.07.2006, 21:56 ) *
2. [...]
Interfejs mówi, które metody dana klasa musi udostępniać, a nie o całym interfejsie danej klasy. Znając intefejs klasy możemy być pewni, co ona potrafi zrobić. Nie wiemy natomiast, czy nie potrafi czegoś jeszcze... Tak to już bywa, że niektóre klasy są zgodne z interfejsem, lecz udostępniają jeszcze coś specjalnego. Dlatego właśnie autor dopisał te metody.


Ale co z tego, że udostępniają coś jeszcze, skoro nie można się do nich odwoływać, bo nie są wymienione w interfejsie?

Cytat(Ja_Szczur @ 31.07.2006, 22:05 ) *
1) głupi przykład, ale:
  1. <?php
  2. class engine
  3. {
  4.  //...
  5.  
  6.  private function deleteAll()
  7.  {
  8. // ...
  9.  }
  10. }
  11.  
  12. $e = new Engine;
  13. $e->load();
  14. $e->run();
  15.  
  16. // ale ze mnie żartowniś!
  17. $e->deleteAll();
  18. ?>


Dobry przykład. Dziękuje.

Cytat(Ja_Szczur @ 31.07.2006, 22:05 ) *
2) pomyśl o tym inaczej:
masz różne klasy, które reprezentują [implementują] marki samochodów [samochód - interfejs]
wymagasz od nich, żeby mogły jechać, otwierać drzwi, mieć klimatyzajcę itd. tongue.gif [metody wymagane w interfejsie]
chcesz pojechać samochodem: wybierając którąkolwiek klasę [mercedes, bmw, fiat] implementującą interfejs samochód, masz pewność, że jest tam metoda go() czy też run() - nie martwisz się o to!

czyli: masz kilka samochodów, jedne z klimatyzacją, inne z barkiem na pokładzie
ale wiesz jedno: wszystkie mają metody run() openDoors() i np. szlagTrafilSilnik() biggrin.gif


Ale ograniczasz się. Nie możesz wykonywać metod, które nie zostały podane w interfejsie. Czy nie lepiej poprostu zbudować podstawową klasę Samochód, która będzie zawierała run(), openDoors() a np klasa Mercedes dziedziczy po klasie Samochod i dodaje nowe metody? Przecież to o wiele prostrze..

Cytat(Ja_Szczur @ 31.07.2006, 22:05 ) *
jeżleli za ciemno wyjaśniłem, daj znać, rzucę przykład na systemie newsów w cms'ie czy coś :]


Jeśli nie mogę zrozumieć sensu interfejsu to myślisz, że połapie się w kodzie jakiegoś CMSa? tongue.gif
Cysiaczek
Zgodze się z Athabusem - klasa implementująca interfejs zyskuje dodatkowy typ, który można potem wymusić gdzieś, lub po prostu sprawdzić. Może to być bardzo przydatne, zwłaszcza, gdy pracujesz na kilku zupełnie ze sobą niepowiązanych obiektach. Będziesz dla nich robił klasę abstrakcyjną? Po co? Niech implementują wspólny interfejs - po tym je poznasz.
bigZbig
Cytat(J4r0d @ 1.08.2006, 21:59 ) *
Ale ograniczasz się. Nie możesz wykonywać metod, które nie zostały podane w interfejsie. Czy nie lepiej poprostu zbudować podstawową klasę Samochód, która będzie zawierała run(), openDoors() a np klasa Mercedes dziedziczy po klasie Samochod i dodaje nowe metody? Przecież to o wiele prostrze..

Interfejs to taki regulamin, ktory okresla jakie metody powinna zawierac klasa, ktora dany interfejs implementuje. Patrzysz na naglowek klasy widzisz ze implementuje interfejs X i wiesz ze napewno ma ona metody, ktorych interfejs X wymaga. Czy Ty zgodnosc metod osiagniesz poprzez dziedziczenie czy np. za pomoca wzorca dekoratora to juz jest Twoja sprawa.
athabus
Cytat(J4r0d @ 1.08.2006, 19:59 ) *
Metody publiczne też możesz wywoływać z odpowiednich miejsc. To Ty piszesz kod, więc wiesz co robisz..


Takie myślenie zawiera pewne błędy
a ) Nie koniecznie to Ty piszesz kod - albo możesz go nie pisać samodzielnie
b ) Kod, który piszesz możesz chcieć wykorzystać za 2 lata - pytanie czy będziesz wtedy miał czas znowu się przegryzać przez to co może zrobić obiekt, czego nie. Które metody miały być wywoływane, a które są publiczne dlatego, że hmmm są itd.
c ) Twój kod być może będą wykorzystywać inne osoby (oczywiście za Twoją zgodą) - wtedy j.w.

Generalnie interfejsy są jednym z narzędzi nowowczesnych języków, które pozwalają na upraszczanie (grupowanie) zależności w kodzie, wymuszania na obiektach danej grupy posiadania pewnych funkcji itp.

Kiedyś czytałem taką książkę o UML, w której autor napisał, że ludzie nie są w stanie ogranąć złożoności, dlatego naturalnym jest, że zjawiska złożone strają się generalizować i grupować. Np. nie rozważają każdej marki samochodu z osobna (z jej wszystkimi bajerami itd) tylko generalizują sobie to do abstakcyjnego pojęcia samochodu czy pojazdu, które w większości przypadków wystarcza - samochód może się przemieszczać, ma silnik, koła itd. W programowaniu stosujemy klasy abstrakcyjne i interfejsy i dziedziczenie w tym samym celu - uproszczenia złożoności.

Inna Kwestia, że takich rzeczy używa się zazwyczaj w większych projektach lub w projektach nad którymi pracuje kilka osób. Jeśli nie czujesz jeszcze potrzeby generalizowania w swoich projektach to prawdopodobnie nie potrzebujesz tego. Ja akurat zacząłem stosować tego typu rozwiązania w C# i uważam, że w php jest znacznie mniej potrzeb wykorzystania tych konstrukcji (pewnie dlatego, że jeszcze słobo znam php i moje projekty nie są zbyt rozbudowane) niż w językach typu C#, C++ czy Java, choć i w php ostatnio zaczynam z nich korzystać coraz częściej.
Ludvik
J4rod: Pisząc kod jest naturalnym, że staramy się uczynić go maksymalnie idiotoodpornym. Czynienie publicznymi metod, które mają sens tylko wewnątrz klasy jest bezsensownym i nikt zdrowy czegoś takiego nie robi... Myślałem, że jest oczywiste, że klasa ma swój interfejs, czyli to co klient może zrobić z obiektem, oraz ukryte przed użytkownikiem szczegóły jej działania... Interfejs powinien być publiczny, a cała reszta prywatna/chroniona. I nie chodzi mi o interfejs w sensie konstrukcji językowej...

Pamiętaj też, że interfejs wymusza zaimplementowanie metod, ale nie broni implementowania tych, które nie zostały w nim wymienione. Możesz się do nich zawsze odwołać, ale musisz mieć pewność, że wiesz co robisz.

  1. <?php
  2. interface Iface {
  3. public function methodOne();
  4. public function methodTwo();
  5. }
  6.  
  7. class ClassOne implements Iface {
  8. public function methodOne() {}
  9. public function methodTwo() {}
  10. }
  11.  
  12. class ClassTwo implements Iface {
  13. public function methodOne() {}
  14. public function methodTwo() {}
  15. public function methodThree() {}
  16. }
  17.  
  18. class ClassThree extends ClassTwo {
  19. }
  20.  
  21. function funcOne(Iface $o) {
  22. $o->methodOne(); // Zawsze OK
  23. $o->methodTwo(); // Zawsze OK
  24. $o->methodThree(); // Niepewne wywołanie... Zwróci błąd w przypadku ClassOne.
  25. }
  26.  
  27. function funcTwo(ClassTwo $o) {
  28. $o->methodOne(); // Zawsze OK
  29. $o->methodTwo(); // Zawsze OK
  30. $o->methodThree(); // Zawsze OK, bo kontrola typów nie dopuści ClassOne
  31. }
  32. ?>
dr_bonzo
Cytat
Skoro możemy używać tylko tych metod, które zostały wymienione w interfejsie to po jakiego grzyba w klasach tworzył inne metody?

W Javie to widac:

  1. <?php
  2. interface Observer
  3. {
  4. public void update( $cos );
  5. }
  6.  
  7. class Window implements Observer
  8. {
  9. // cholercia, jak ja dawno nie kodowalem...
  10. public void open() {....}
  11. public void rename( $newName ) {....}
  12. public void update( $cos )
  13.  {
  14.  .... blalbabla..
  15.  }
  16. }
  17.  
  18. class Foo implements Observer
  19. {
  20.  public void bar() {...}
  21. public void update( $cos )
  22.  {
  23.  .... blalbabla..
  24.  }
  25. }
  26.  
  27. class Model extends Observable
  28. {
  29.  public boolean registerObserver( Observable obj )
  30.  {
  31. // tutaj dla $obj mozesz wywolac TYLKO metody z interfejsu Observable
  32. obj.update();
  33. // obj.bar() nie przejdzie
  34. }
  35. }
  36.  
  37. Window window = new Window();
  38. Foo foo = new Foo();
  39.  
  40. window.open();
  41. window.rename( "lol" );
  42. foo.bar();
  43.  
  44. Model model = new Model();
  45. model.registerObserver( window );
  46. model.registerObserver( foo );
  47. ?>
bigZbig
Cytat(dr_bonzo @ 3.08.2006, 11:59 ) *
W Javie to widac:
...

Przepraszam dr_bonzo, ale co widac, bo jak dal mnie z Twojego przykladu nic nie wynika odnosnie sensu uzywania metod innych niz publiczne.
dx9
Dlaczego używać metod prywatnych lub chronionych? Z powodów bezpieczeństwa. Wyobraź sobie np. logowanie. oczywiście chcesz, żeby dało się zalogować użytkownika wpisując login i hasło, ale także tylko mając id i hash sprawdzający. Jeśli zadeklarujesz sobie funkcję (prywatną lub chronioną) authorize($id), która odpowiadać będzie za ustawienie zmiennych sesyjnych i podniesienie uprawnień, to metodę tą wywołasz tylko i wyłącznie z tej klasy. Jesli natomiast będzie funkcją public, to ktoś moze wywołać tą funkcje spoza klasy logując sie na danego usera tylko podając id. Takie coś powoduje niebezpieczeństwo w przypadku błędu w kodzie.

A dlaczego wyodrębnić można metode authorize? Po to, żeby nie powtarzać 2 razy tego samego kodu. Czy wybierzemy protected czy private zależy od tego czy chcemy mieć możliwość używania tej metody w klasach pochodnych
NuLL
Ja stosuje metody prywatne po to aby ograniczyc dlugosc metod - kod lepiej wyglada kiedy metody maja 40 linii a nie po 100 winksmiley.jpg Pozatym kiedy trzeba powtorzyc jakas czesc kodu raczej tez stosuje sie metody prywatne smile.gif
Jarod
Cytat(Ludvik @ 3.08.2006, 09:05 ) *
  1. <?php
  2. function funcTwo(ClassTwo $o) {
  3. $o->methodOne(); // Zawsze OK
  4. $o->methodTwo(); // Zawsze OK
  5. $o->methodThree(); // Zawsze OK, bo kontrola typów nie dopuści ClassOne
  6. }
  7. ?>


function funcTwo(ClassTwo $o) ponieważ wymuszasz, aby przeakzany argument był instacją klasy ClassTwo

Cytat(Ludvik @ 3.08.2006, 09:05 ) *
  1. <?php
  2. function funcOne(Iface $o) {
  3. $o->methodOne(); // Zawsze OK
  4. $o->methodTwo(); // Zawsze OK
  5. $o->methodThree(); // Niepewne wywołanie... Zwróci błąd w przypadku ClassOne.
  6. }
  7. ?>


function funcOne(Iface $o)
A tutaj co wymuszasz? Żeby przekazywany argument implementował interfejs czy, żeby to był obiekt który implementuje interfejs?
Cysiaczek
Obiekt implementujący interfejs smile.gif
Pisałem już kiedyś. Jak klasa implwementuje interfejs, to zyskuje nowy typ, będący nazwą intefejsu.
Czyli klasa.
  1. <?php
  2. class A implements viewable{
  3. }
  4. ?>

To klasa typu A oraz viewable. Można wymusić jej obiekt zarówno po nazwie klasy, jak również po nazwie interfejsu.

Czyli kod:
  1. <?php
  2. function dopisz_wg_interfejsu(viewable $obiekt){}
  3. //lub
  4. function dopisz_wg_klasy($obiekt){}
  5. ?>


Pozdrawiam.
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.