![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 1 190 Pomógł: 27 Dołączył: 23.04.2005 Ostrzeżenie: (0%) ![]() ![]() |
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
Plik class.Door.php
Plik class.Jar.php
i wreszcie plik główny testOpenable.php
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ć? -------------------- ”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335) |
|
|
![]()
Post
#2
|
|
![]() Grupa: Przyjaciele php.pl Postów: 698 Pomógł: 3 Dołączył: 28.03.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
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. -------------------- |
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 115 Pomógł: 0 Dołączył: 4.12.2005 Skąd: Strzyżów Ostrzeżenie: (0%) ![]() ![]() |
1) głupi przykład, ale:
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. ![]() 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() ![]() jeżleli za ciemno wyjaśniłem, daj znać, rzucę przykład na systemie newsów w cms'ie czy coś :] -------------------- "No bo z fasolą to człowiek przynajmniej wie, na czym stoi..."
Pomniejsze bóstwa, Terry Pratchett php :* |
|
|
![]()
Post
#4
|
|
Grupa: Przyjaciele php.pl Postów: 7 494 Pomógł: 302 Dołączył: 31.03.2004 Ostrzeżenie: (0%) ![]() ![]() |
Przenoszę z Przedszkola na php :: PHP5
|
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 139 Pomógł: 0 Dołączył: 14.07.2006 Ostrzeżenie: (10%) ![]() ![]() |
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... |
|
|
![]()
Post
#6
|
|
![]() Grupa: Przyjaciele php.pl Postów: 698 Pomógł: 3 Dołączył: 28.03.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
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
![]() -------------------- |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 139 Pomógł: 0 Dołączył: 14.07.2006 Ostrzeżenie: (10%) ![]() ![]() |
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." ![]() dopiero tu jest sens Cytat Prywatna po to, aby nikt nie odwołał się do metody nie ważne ![]() |
|
|
![]()
Post
#8
|
|
![]() Grupa: Zarejestrowani Postów: 1 660 Pomógł: 13 Dołączył: 9.06.2004 Skąd: Wrocław i okolice Ostrzeżenie: (0%) ![]() ![]() |
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. ![]() ![]() -------------------- |
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 2 262 Pomógł: 21 Dołączył: 3.05.2004 Skąd: Sopot, Krakow, W-wa Ostrzeżenie: (0%) ![]() ![]() |
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 ![]() 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 ![]() ![]() 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 ![]() ![]() Ten post edytował NuLL 1.08.2006, 03:16:25 -------------------- Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
|
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 139 Pomógł: 0 Dołączył: 14.07.2006 Ostrzeżenie: (10%) ![]() ![]() |
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 ![]() 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 |
|
|
![]()
Post
#11
|
|
![]() Grupa: Developerzy Postów: 823 Pomógł: 12 Dołączył: 18.12.2005 Ostrzeżenie: (0%) ![]() ![]() |
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 ![]() p.s. proszę wziąźć sobię tą uwagę do serca (mówie do tych którzy radzą, ale niejaśnie jak im się zdaje ![]() Ten post edytował Athlan 1.08.2006, 09:40:44 -------------------- Portfolio: Vgroup.pl | athlan.pl | Test.php.pl - sprawdź się z wiedzy o PHP i ułóż własne pytania!
Pomogłem? Kliknij |
|
|
![]()
Post
#12
|
|
![]() Grupa: Przyjaciele php.pl Postów: 698 Pomógł: 3 Dołączył: 28.03.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
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. -------------------- |
|
|
![]()
Post
#13
|
|
![]() Grupa: Zarejestrowani Postów: 1 660 Pomógł: 13 Dołączył: 9.06.2004 Skąd: Wrocław i okolice Ostrzeżenie: (0%) ![]() ![]() |
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 ![]() ![]() Dobrze wiesz, że nie o to mi chodziło ![]() 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% ![]() -------------------- |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 898 Pomógł: 48 Dołączył: 2.11.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
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. |
|
|
![]()
Post
#15
|
|
Grupa: Zarejestrowani Postów: 1 190 Pomógł: 27 Dołączył: 23.04.2005 Ostrzeżenie: (0%) ![]() ![]() |
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.. 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? 1) głupi przykład, ale:
Dobry przykład. Dziękuje. 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. ![]() 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() ![]() 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.. 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? ![]() -------------------- ”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335) |
|
|
![]()
Post
#16
|
|
![]() Grupa: Moderatorzy Postów: 4 465 Pomógł: 137 Dołączył: 26.03.2004 Skąd: Gorzów Wlkp. ![]() |
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.
-------------------- 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. |
|
|
![]()
Post
#17
|
|
![]() Grupa: Zarejestrowani Postów: 740 Pomógł: 15 Dołączył: 23.08.2004 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
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. -------------------- bigZbig (Zbigniew Heintze) | blog.heintze.pl
|
|
|
![]()
Post
#18
|
|
![]() Grupa: Zarejestrowani Postów: 898 Pomógł: 48 Dołączył: 2.11.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
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. Ten post edytował athabus 2.08.2006, 08:53:48 |
|
|
![]()
Post
#19
|
|
![]() Grupa: Przyjaciele php.pl Postów: 698 Pomógł: 3 Dołączył: 28.03.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
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.
Ten post edytował Ludvik 3.08.2006, 10:07:26 -------------------- |
|
|
![]()
Post
#20
|
|
![]() Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
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:
-------------------- Nie lubię jednorożców.
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 20.06.2025 - 12:46 |