![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Mam jedno pytanie: Do czego tak na prawdę mogą się przydać interfejsy w programowaniu? Bo za cholerę nie wiem. Szukam unikalnego zastosowania, którego nie dało by się z powodzeniem zastąpić czymś innym i nie znajduję. Do czego to więc?
|
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 651 Pomógł: 28 Dołączył: 4.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
Jeśli chodzi o interfejsy w php, to mogą się one przydać np. do budowania prototypu dla jakiegoś zestawu klas, do wymuszania stworzenia konkretnej metody (lub metod) w różnych klasach, do ujednolicenia lub usystematyzowania wybranego zestawu klas. Implementując interfejs nie zapomnimy o żadnej potrzebnej metodzie. Czasem zdarza się, że jakaś aplikacja ma wiele kontrolerów w postaci klas, które mają bardzo podobną budowę tylko pobierają różne dane i na różny sposób je prezentują. Te kontrolery muszą mieć konkretne metody o konkretnych nazwach, które powielają się każdym z nich, ale zwracają co innego. Za pomocą interfejsu możemy automatycznie zapewnić spójność tych kontrolerów i zapewnić uruchomienie każdego kontrolera tylko w przypadku, gdy posiada wszystkie potrzebne metody.
|
|
|
![]()
Post
#3
|
|
Grupa: Moderatorzy Postów: 8 989 Pomógł: 1550 Dołączył: 8.08.2008 Skąd: Słupsk/Gdańsk ![]() |
Przydają się np do tego jak tworzysz klasy elementów formularza. Chcesz, żeby każda klasa elementu musiała zdefiniować pewne metody, właściwości np getHtml, isValid itd.
Dzięki temu masz pewność, że klasy które implementują ten interfejs, będą posiadały podane metody. Różnica pomiędzy interfejsem a klasą abstrakcyjną to np taka, że możesz implementować wiele interfejsów a dziedziczyć po jednej klasie. |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 651 Pomógł: 28 Dołączył: 4.12.2004 Ostrzeżenie: (0%) ![]() ![]() |
Cytat Różnica pomiędzy interfejsem a klasą abstrakcyjną to np taka, że możesz implementować wiele interfejsów a dziedziczyć po jednej klasie. Nie tylko. W klasie abstrakcyjnej można zdefiniować całe ciało metody, a w interfejsie tylko jej prototyp (dostępność, nazwa, parametry). |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Ale to w takim razie sprowadza się do tego że do interfejs nie daje mi żadnej nowej funkcjonalności jaką dawał by mi klasa abstrakcyjna (inna sprawa że klasa abstrakcyjna nie daje mi niczego czego nie dawała by mi "zwykła" klasa). Bo co za różnica czy dziedziczę po x klas i implentuję y interfejsów, skoro mogę dziedziczyć po x+y klas. A tym samym nadal nie widzę realnej potrzeby zastosowania interfejsów.
Oczywiście nie chcę zaczynać dyskusji o wyższości kodowania z użyciem interfejsów nad kodowaniem bez ich użycia, bo już za duży ze mnie chłopczyk na bójki o niczym z piaskownicy. Oraz oczywiście rozumiem że interfejsy, czy klasy abstrakcyjne pozwalają na uniknięcie pewnych błędów, ale z drugiej strony dobrze opisany kod + testy jednostkowe też na to pozwalają, i też o tym nie chcę rozmawiać. Chce wiedzieć czy interfejs ma w jakieś unikalne zastosowanie którego gdzie nie da się go zastąpić niczym innym. Bo jak na razie dla mnie interfejs to taka klasa abstrakcyjna bez definicji metod, a klasa abstrakcyjna to taka klasa której obiektu nie można utworzyć i... tyle. |
|
|
![]()
Post
#6
|
|
Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
Cytat Bo co za różnica czy dziedziczę po x klas i implentuję y interfejsów, skoro mogę dziedziczyć po x+y klas. A tym samym nadal nie widzę realnej potrzeby zastosowania interfejsów. Cytat Chce wiedzieć czy interfejs ma w jakieś unikalne zastosowanie którego gdzie nie da się go zastąpić niczym innym. Bo jak na razie dla mnie interfejs to taka klasa abstrakcyjna bez definicji metod, a klasa abstrakcyjna to taka klasa której obiektu nie można utworzyć i... tyle. 1. Chodzi o to ze mozesz dziedziczyc TYLKO po 1 klasie (pomijam np C++ gdzie mozesz po wielu, ale w nim nie masz interfejsow, ktore niejako zastepuja wielokrotne dziedziczenie). 2. Uzywasz edytora z podpowiadaniem skladni? Albo pokoduj troche w Javie/C# - wymuszanie okreslania typow podpowi ci po co sa interfejsy. 3. Cytat Oraz oczywiście rozumiem że interfejsy, czy klasy abstrakcyjne pozwalają na uniknięcie pewnych błędów, ale z drugiej strony dobrze opisany kod + testy jednostkowe też na to pozwalają, i też o tym nie chcę rozmawiać. Tak, bez interfejsow wszytko nadal bedzie dzialac. Interfejsy w php sa wskazowka projektowa: czemu te 5 klas ma takie same metody? co musze zrobic zeby napisac 6ta klase, bo chce zmienic implementacje np. session handlera. W innych jezykach sa tez obejsciem okreslania typow dla zmiennych - bo masz N klas niepolaczonych ze soba, zadna nie dziedziczy po drugiej, ale maja wspolma metode, np validate(), no i jakos musisz okreslic typ przy definiowaniu zmiennej. Uzywasz: Validator validator; gdzie Validator to nazwa interfejsu z metoda validate(). Dzieki temu kompilator wie jakich metod mozesz uzywac na obiektach przypisanych do tej zmiennej. |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
1. Chodzi o to ze mozesz dziedziczyc TYLKO po 1 klasie (pomijam np C++ gdzie mozesz po wielu, ale w nim nie masz interfejsow, ktore niejako zastepuja wielokrotne dziedziczenie). 2. Uzywasz edytora z podpowiadaniem skladni? Albo pokoduj troche w Javie/C# - wymuszanie okreslania typow podpowi ci po co sa interfejsy. 3. Tak, bez interfejsow wszytko nadal bedzie dzialac. Interfejsy w php sa wskazowka projektowa: czemu te 5 klas ma takie same metody? co musze zrobic zeby napisac 6ta klase, bo chce zmienic implementacje np. session handlera. W innych jezykach sa tez obejsciem okreslania typow dla zmiennych - bo masz N klas niepolaczonych ze soba, zadna nie dziedziczy po drugiej, ale maja wspolma metode, np validate(), no i jakos musisz okreslic typ przy definiowaniu zmiennej. Uzywasz: Validator validator; gdzie Validator to nazwa interfejsu z metoda validate(). Dzieki temu kompilator wie jakich metod mozesz uzywac na obiektach przypisanych do tej zmiennej. Ad 1: OD KIEDY mogę dziedziczyć TYLKO po 1 klasie? Ad 3: Ja nie pytam o konkretny język programowania tylko o teorię, po to temat w Hydeparku. Ale to jest właśnie przykład o który mi chodziło, dziękuję. |
|
|
![]()
Post
#8
|
|
Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
1. A od kiedy mozesz? (IMG:style_emoticons/default/biggrin.gif) Na pewno *mozesz* w C++, w Javie nie mozesz, w PHP nie mozesz (http://www.php.net/manual/en/keyword.extends.php ) , w Rubym nie mozesz (tam masz moduly, cos blizej wielodziedziczeniu niz interfejsom), C# - tez nie (googlilem przed chwila)
3. Cytat Ad 3: Ja nie pytam o konkretny język programowania tylko o teorię, Ciezko mowic o teorii kiedy kazdy jezyk jest inny. Mozemy mowic o interfejsach, kiedy za czasow powstawania C++ ich nie bylo. Java powstala jako "better c++", pozbyli sie wielodziedziczenia, wprowadzili interfejsy itp. Ten post edytował dr_bonzo 2.09.2009, 00:28:24 |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 1 415 Pomógł: 117 Dołączył: 7.09.2005 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Przede wszystkim interfejsy umożliwiają poprawną modularyzację aplikacji i ułatwiają modelowanie zależności pomiędzy obiektami. Są bardzo przydane przy projektowaniu modeli (domain models).
Pokaże to na prostym przykładzie wyszukiwarki produktów.
Wszyscy wiemy jak wiele jest rozwiązań dotyczących wyszukiwarek, zatem:
Użycie mogłoby wyglądać w ten sposób:
W powyższym przykładzie jak krowie na rowie wymodelowaliśmy zależność Produkt-Wyszukiwarka przy zapisywaniu i aktualizacji obiektu. Ta zależność może wyglądać tak:
Jeżeli do projektu jeszcze nie wybrano mechanizmu wyszukiwania, można by również zaimplementować pusty obiekt NoneProductSearch, który by zwyczajnie nic nie indeksował i wracał pustą tablicę przy wyszukiwaniu. ------------------------------------------------ Cały kłopot z programowaniem na interfejsach - jak również niechęć programistów - tkwi w instancjonowaniu obiektów. Trzeba się trochę nagimnastykować. 1. Operator new
Zwyczajne tworzenie obiektów już nie wystarcza. Potrzeba czegoś bardziej elastycznego, bo można skończyć (np. przy przesiadce z Lucene na Sphinxa) zmieniając nazwę obiektu wyszukiwarki w każdym miejscu, gdzie się jej używa 2. Wzorce kreacyjne i pochodne
Już lepiej. Konfiguracja obiektu odbywa się w jednym miejscu, ale od ilości pisaniny (np. fabryka do każdego obiektu (IMG:style_emoticons/default/blink.gif) ) można szlak trafić.
3. Bardziej kompleksowe rozwiązania. Przykładem takowych są kontenery IoC. Całość tworzenia obiektów jest przekazywana do nich w formie np. wygodnej xmlowej konfiguracji.
|
|
|
![]()
Post
#10
|
|
Grupa: Moderatorzy Postów: 4 465 Pomógł: 137 Dołączył: 26.03.2004 Skąd: Gorzów Wlkp. ![]() |
@sztosz - w OOP jest kilka tematów na temat interfejsów, niemal każdy traktuje o sensie ich istnienia. Są tam wymienione wszystkie zalety i wady stosowania interfejsów, wiec aprawde nie rozumiem, po co kolejny temat o tym samym :/
Przenoszę |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
1. A od kiedy mozesz? (IMG:style_emoticons/default/biggrin.gif) Na pewno *mozesz* w C++, w Javie nie mozesz, w PHP nie mozesz, w Rubym nie mozesz,C# - tez nie Ale w Pythonie mogę, w Perlu mogę. Dziękuję wszystkim za komentarze. Cysiaczek ma rację, niepotrzebnie zakładałem taki temat. Czytam i czytam i wychodzi na to że Interfejsy nie dają żadnej niezastępowalnej funkcjonalności. |
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat Czytam i czytam i wychodzi na to że Interfejsy nie dają żadnej niezastępowalnej funkcjonalności. W PHP podstawowym celem interface-ów jest zagwarantowanie, że to z czym masz do czynienia jest tym czego oczekujesz - przynajmniej w części z której będziesz korzystać.I takiej funkcjonalności nie dają Ci żadne inne elementy języka. btw: z wielokrotnym dziedziczeniem nie chodziło o coś takiego: Tylko o Taka konstrukcja w PHP jest niemożliwa. |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Mnie fascynuje Python, PHP denerwuje. Do zagwarantowania że to z czym mam do czynienia jest tym czego oczekuję nie są mi potrzebne interfejsy a specyfikacja, dokumentacja raczej. Poza tym mogę zawsze dziedziczyć po klasie abstrakcyjnej, inna sprawa że nie ma klas abstrakcyjnych w Pythonie, ale to też jest banalnie poste do zaimplentowania. Teraz nasuwa się pytanie: Kiedy wyrzucany jest błąd związany z tym że klasa nie poprawnie implementuje jakiś interfejs, w momencie tworzenia obiektu klasy, czy.... no kiedy?
btw: z wielokrotnym dziedziczeniem nie chodziło o coś takiego: Tylko o Taka konstrukcja w PHP jest niemożliwa. Dla mnie wielokrotne dziedziczenie to coś takiego:
rezultat: Kod a b I cały czas o tym mówię. Ten post edytował sztosz 2.09.2009, 14:42:27 |
|
|
![]()
Post
#14
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat Mnie fascynuje Python, PHP denerwuje. Mnie też PHP wieloma elementami denerwuje i staram się od niego odejść na rzecz m.in. Javy - ale jest to nadal potężne narzędzie, które oferuje na prawdę wiele.Cytat Do zagwarantowania że to z czym mam do czynienia jest tym czego oczekuję nie są mi potrzebne interfejsy a specyfikacja, dokumentacja raczej. Dokumentacja dokumentacją, kod kodem.Takie wymuszenie jest dużo wygodniejsze niż patrzenie po dokumentacji. Poza tym ewentualny błąd: Cytat Metoda A:abc() wymaga by pierwszy argument był MyInterface-m Jest dużo wygodniejszy niżCytat Nie można wykonać metody def() na obiekcie XXX - linia 123, plik abc Cytat Poza tym mogę zawsze dziedziczyć po klasie abstrakcyjnej No właśnie klasy abstrakcyjnej nie możesz użyć zawsze... ba! Użycie jej jest możliwe jedynie w podstawowych przypadkach typu:Co w przypadku gdy Square dziedziczy już po czymś? Nie możesz w nieskończoność dziedziczyć, bo w końcu byś sens tego stracił: Zwierzę -> Ssak -> Człowiek - to jak najbardziej ok. Zwierzę -> Porusza się -> Oddycha -> Mówi -> Ssak -> Człowiek? Ssaki są rozwinięciem "mowy"? Z interfaceami jest to logiczne: Zwierzę(porusza się, oddycha, mówi) -> Ssak -> Człowiek. Cytat inna sprawa że nie ma klas abstrakcyjnych w Pythonie, ale to też jest banalnie poste do zaimplentowania. A w PHP nie ma klas wewnętrznych... ale co to ma do rzeczy?Cytat Kiedy wyrzucany jest błąd związany z tym że klasa nie poprawnie implementuje jakiś interfejs, w momencie tworzenia obiektu klasy, czy.... no kiedy? W przypadku PHP - sprawdzanie czy dana klasa implementuje wszystkie interface-y wykonywane jest w momencie tworzenia obiektu - ale to w manualu można wyczytać.Cytat Dla mnie wielokrotne dziedziczenie to coś takiego: W PHP coś takiego jest niemożliwe.
|
|
|
![]()
Post
#15
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
No i to jest właśnie ten problem którego chciałem uniknąć. Założyłem temat na Hydeparku, a nie w PHP żeby mi nie tłumaczono co można w PHP a czego nie, bo to mnie zupełnie nie interesuje. Chciałem dowiedzieć się czegoś o interfejsów od bardziej doświadczonych forumowiczów, a i tak dowiaduję się "Co mi da używanie interfejsów w PHP". Jeśli zaraz nie padnie stwierdzenie w stylu "A czegoś się spodziewał, to przecież forum PHP!'' to będę zaskoczony.
Z tego tematu wynika że w PHP interfejs jest tylko pomocnikiem by programista widział co musi zaimplentować, natomiast i tak musi dla każdej klasy implementującej dany interfejs napisać ciało metody. Dziedzicząc zaś po kilku klasach (co w PHP jest nie możliwe) nie musimy tego robić, ale nic nie stoi na przeszkodzie przesłaniania metod klas po których dziedziczymy (owszem tu są tez niedogodności, ale tylko jeśli nieuważnie kodujemy).
I nie potrzeba mi interfejsów. |
|
|
![]()
Post
#16
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Ahh... zapomniałem, że temat miał być ogólny - mój błąd. Przeglądałem przez "Pokaż najnowsze" i nie zwróciłem nawet uwagi na dział.
Wracając do przykładu z królestwem zwierząt. Co wg Ciebie miała by robić (abstrakcyjna) klasa "porusza się"? Przecież człowiek porusza się w zupełnie inny sposób niż bardzo podobna do niego małpa nie wspominając np. o psie czy delfinie (a wszystkie te zwierzęta dziedziczą po: Zwierzę -> Ssak). Tak więc nie ma tutaj po prostu czego dziedziczyć bo każdy z obiektów wykonuje to zupełnie inaczej. Ale z zewnątrz mamy tak jakby ten sam interface, bo każdy z tych wymienionych obiektów potrafi poruszyć się w prawo, w lewo, do przodu oraz do tyłu. Jeżeli bardzo chciałbyś użyć tutaj dziedziczenia to musiałaby to być abstrakcyjna klasa definiująca jedynie abstrakcyjne metody, a język prog. musiałby umożliwić wielokrotne dziedziczenie. interface natomiast przynosi nam bardzo wygodny mechanizm identyfikacji "możliwości" obiektu: Tak więc nawet w PHP (chociaż ten przykład jest od tego języka dosyć mocno oderwany) interface-y pełnią dużo większą rolę niż tylko "pomocnicza". Ten post edytował Crozin 2.09.2009, 16:27:54 |
|
|
![]()
Post
#17
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
O widzisz, i zaczynam poniekąd znajdować zastosowanie dla interfejsu.
|
|
|
![]()
Post
#18
|
|
Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
Cytat Z tego tematu wynika że w PHP interfejs jest tylko pomocnikiem by programista widział co musi zaimplentować, natomiast i tak musi dla każdej klasy implementującej dany interfejs napisać ciało metody. Dziedzicząc zaś po kilku klasach (co w PHP jest nie możliwe) nie musimy tego robić, ale nic nie stoi na przeszkodzie przesłaniania metod klas po których dziedziczymy (owszem tu są tez niedogodności, ale tylko jeśli nieuważnie kodujemy). Tak (IMG:style_emoticons/default/smile.gif) To prawda. Interfejsy sa obejsciem wielokrotnego dziedziczenia (rozwiazaniem zaproponowanym zamiast W. D.), i ich wada jest to ze nie moga zawierac cial metod - bo tak ich tworcy sobie zalozyli (IMG:style_emoticons/default/smile.gif) Pewnie z perspektywy czasu nie jest to najlepsze rozwiazanie, i wielodziedziczenie sie przydaje (dla php, hmm, chyba mielem kilka chwil gdzie bym z niego skorzystal, ale nie jestem w stanie wymienic - o musialem zduplikowac kilka metod w dwoch roznych hierarchiach klas, a takto podziedziczylbym z 3ciej klasy i po problemie). PHP poniekad wzorowalo sie na javie w OOP. Jednak w Javie oprocz interfejsow masz tez klasy wewnetrzne, ktore to pozwalaja w pewien sposob wykonac wielodziedziczenie, konkretniej - dodac do klasy zbioru metod z cialami, jednoczesnie kozystajac z pojedynczego dziedziczenia - http://www.javaworld.com/javaworld/jw-10-2...4-multiple.html . |
|
|
![]()
Post
#19
|
|
Grupa: Zarejestrowani Postów: 2 592 Pomógł: 445 Dołączył: 12.03.2007 Ostrzeżenie: (0%) ![]() ![]() |
Osobiście dla mnie interfejsy są zasadne w kilku przypadkach:
Pluginy - gdy plugin musi mieć określone metody (instalacja, dodanie do menu w panelu, sprawdzenie wersji, wyswietlenie na stronie, etc). Interfejs wymusza zastosowanie tych metod, dzięki czemu wiem, że nie dołączę pluginu bez instalatora. Drivery - ostatnio pisałem loggera. Przedstawię na przykładzie:
Każda następna klasa implementująca logInterface musi posiadać te 3 metody. Dzięki temu mogę utworzyć klasę log która będzie przyjmowała obiekty klas implementujących logInterface. W przypadku zmian, dodaniu innego sterownika logów, użycie będzie zawsze takie samo: Wystarczy na początku skryptu zmienić sterownik:
I już mogę używać logowania do bazy zamiast do pliku, bez zmian w całym kodzie. Można to osiągnąć przez użycie klasy abstrakcyjnej. W tym przypadku logowanie do pliku odbywa się zupełnie inaczej niż logowanie do bazy. Zatem klasa abstrakcyjna musiałby mieć tylko zarysy metod, bez ciała - co w rezultacie sprowadza się do interfejsu. Interfejs dodaje warstwę abstrakcji, którą w przypadku zmian łatwo wymienić nie ingerując w cały kod wykorzystujący dane rozwiązanie. |
|
|
![]()
Post
#20
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
@vokiel: Ale do tego żeby to zrobić, nie potrzebujesz ani interfejsu, ani klasy abstrakcyjnej, wystarczy po prostu mieć dane metody w klasie sterownika loggera. Jak na razie wszyscy piszą o tym gdzie można użyć interfejsu, ale ja sam potrafię znaleźć miliony zastosowań dla interfejsu, lecz nie w tym rzecz. Jak na razie wiem, że w językach które nie mogą dziedziczyć po wielu klasach interfejs jest "kulawym"* zastępcą dziedziczenia po wielu klasach. Ale nie widzę nigdzie przykładu gdzie interfejs jest nie do zastąpienia w bardzo prosty sposób, a tego szukam.
Przykład ~Crozin'a z "object x is instance of Class Y" tam gdzie jest dziedziczenie po wielu klasach nie potrzebuje atrybutu, tam gdzie nie ma tego można i chyba nawet lepiej zastąpić to jakimś atrybutem klasy bazowej. Bo "możeChodzić" pasuje mi bardziej jako booleanowski atrybut a nie jakiaś klasa czy interfejs. W konstruktorze grzybka ustawiamy "możeChodzić = False" a mrówki "możeChodzić = True". Ale za daleko wybiegam chyba z myślami poza temat. ___________ *Kulawym ponieważ nie pozwala tworzyć w interfejsie ciała metody. Ale tak to zostało zaprojektowane i nie mnie oceniać czy to źle czy dobrze. |
|
|
![]()
Post
#21
|
|
Grupa: Zarejestrowani Postów: 2 592 Pomógł: 445 Dołączył: 12.03.2007 Ostrzeżenie: (0%) ![]() ![]() |
Cytat Ale nie widzę nigdzie przykładu gdzie interfejs jest nie do zastąpienia w bardzo prosty sposób, a tego szukam. Raczej takiego przykładu nie znajdziesz, większość (jeśli nie wszystko) da się zrobić na wiele sposobów, czasem dookoła, ale jednak.Ja osobiście, w przypadku, gdy nie zawrę metody w klasie implementującej po interfejsie wolę jak dostaję komunikat, który nawet pokaże jaki interfejs i jaka metoda została pominięta, niż gdy ma to się ujawnić w momencie próby użycia danej metody. W przypadku aplikacji, która daje możliwość dodawania modułów. PHPdoc interfejsu jest dość wygodnym rozwiązaniem. Tak sobie teraz myślę... Interfejsy dają wielodziedziczenie, jednak tylko pozorne, bo ciała metod i tak trzeba pisać od nowa. Dopiero interfejsy + klasy abstrakcyjne dają możliwość dziedziczenia po wielu klasach z wykorzystaniem już napisanego kodu. |
|
|
![]()
Post
#22
|
|
Grupa: Moderatorzy Postów: 15 467 Pomógł: 1451 Dołączył: 25.04.2005 Skąd: Szczebrzeszyn/Rzeszów ![]() |
Teraz moje trzy grosze. ;p
Z praktycznego punktu widzenia, to chyba jedyny sensowny przykład użytkowania interfejsów w PHP właśnie z tego względu, że nie można definiować ciał metod. Z tym MozeSiePoruszac, to może nieco abstrakcyjnie, ale można by było to zdefiniować mniej więcej tak: mamy jakąś bibliotekę, która jest zależna tylko od bazy; modele mogą operować na danych z DB albo i z innego źródła, więc modele można by implementować mniej więcej tak:
i np. w helperze sprawdzasz:
Jeśli chodzi o pozostałe przypadki, to w PHP interfejsy są raczej nieco ubogie w praktyczne zastosowanie i wymusza dodatkowe parsowanie kodu... Może się kiedyś doczekamy normalnych interfejsów. (IMG:style_emoticons/default/biggrin.gif) |
|
|
![]()
Post
#23
|
|
Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
@sztosz
Cytat Jak na razie wiem, że w językach które nie mogą dziedziczyć po wielu klasach interfejs jest "kulawym"* zastępcą dziedziczenia po wielu klasach. Ale nie widzę nigdzie przykładu gdzie interfejs jest nie do zastąpienia w bardzo prosty sposób, a tego szukam. Obiektywnie interfejsy maja duzo mniejsza funkcjonalnosc niz klasy abstrakcyjne (nie maja cial metod). W polaczeniu z konkretnym jezykiem programowania, interfejs i k.abstr. nabywaja nowych wlasciwosci. Chcesz przyklad gdzie " interfejs jest nie do zastąpienia " ? - Uzyj, "wielodziedziczenia" w php, czy tez javie. Czemu interfejs jest tu lepszym rozwiazaniem? BO NIE MA INNEGO - w php nie masz wielodziedziczenia, rozszerzenia klasy juz uzyles, wiec musisz skorzystac z interfejsu. Cytat @vokiel: Ale do tego żeby to zrobić, nie potrzebujesz ani interfejsu, ani klasy abstrakcyjnej, wystarczy po prostu mieć dane metody w klasie sterownika loggera No pewnie ze wystarcza metody, ale interfejs jest hmm, jak to nazwac, elementem projektowym, dokumentujacym ten zestaw metod jaki implementujesz. |
|
|
![]()
Post
#24
|
|
Grupa: Moderatorzy Postów: 4 465 Pomógł: 137 Dołączył: 26.03.2004 Skąd: Gorzów Wlkp. ![]() |
Dziedziczenie to w większości przypadków zło wcielone. Tym bardziej dziedziczenie wielu z klas.
Nie na darmo jeden w twórców Javy (chyba nawet sam James Gosling) powiedział, że jeśli miałby coś zmienić w tym języku, to wywalił by dziedziczenie (IMG:style_emoticons/default/smile.gif) Interfejsy mają dać typ, metody, pomóc zorganizować projekt. Faktycznie przy codziennej klepaninie nie są przydatne, przynajmniej mi. Pozdrawiam |
|
|
![]()
Post
#25
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Dziedziczenie to w większości przypadków zło wcielone. Tym bardziej dziedziczenie wielu z klas. Nie na darmo jeden w twórców Javy (chyba nawet sam James Gosling) powiedział, że jeśli miałby coś zmienić w tym języku, to wywalił by dziedziczenie (IMG:style_emoticons/default/smile.gif) Ok, ale dlaczego dziedziczenie to zło? |
|
|
![]()
Post
#26
|
|
Grupa: Moderatorzy Postów: 4 069 Pomógł: 497 Dołączył: 11.05.2007 Skąd: Warszawa ![]() |
Bo w większości przypadków jest zbędne , a początkujący OOPowcy wciskają je gdzie się da (IMG:style_emoticons/default/smile.gif)
Oczywiście czasem jest przydatne ale czasem. |
|
|
![]()
Post
#27
|
|
Grupa: Moderatorzy Postów: 6 072 Pomógł: 861 Dołączył: 10.12.2003 Skąd: Dąbrowa Górnicza ![]() |
Pierwsze słyszę opinię, że dziedziczenie to zło. Moglibyście rozwinąć temat?
|
|
|
![]()
Post
#28
|
|
Grupa: Zarejestrowani Postów: 1 415 Pomógł: 117 Dołączył: 7.09.2005 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Pierwsze słyszę opinię, że dziedziczenie to zło. Moglibyście rozwinąć temat?
a dalej magia:
Bez żadnego pomyślunku. |
|
|
![]()
Post
#29
|
|
Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat Bo w większości przypadków jest zbędne latanie heliktoperem z domu do pracy też w większości przypadków jest zbędne. mam na podstawie tego rozumieć ze heliktoptery to zło wcielone?bezsensowna argumentacja (IMG:style_emoticons/default/tongue.gif) |
|
|
![]()
Post
#30
|
|
Grupa: Moderatorzy Postów: 6 072 Pomógł: 861 Dołączył: 10.12.2003 Skąd: Dąbrowa Górnicza ![]() |
Równie dobrze można powiedzieć, że klasy to (IMG:style_emoticons/default/aaevil.gif) ponieważ można do nich wpakować czysto strukturalny kod.
|
|
|
![]()
Post
#31
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Używanie intefejsów jest zbędne, a prawie wszyscy PHPowcy wciskają je gdzie się da. (IMG:style_emoticons/default/tongue.gif)
A co do samego dziedziczenia, to fajnie jest opisane po co to i gdzie się przydaje w Thinking in Java. |
|
|
![]()
Post
#32
|
|
Grupa: Moderatorzy Postów: 4 069 Pomógł: 497 Dołączył: 11.05.2007 Skąd: Warszawa ![]() |
Czy napisałem że zło wcielone? Napisałem że przydatne czasem. Czyli latanie helikopterem aby ratować ludzi w górach a nie wycieczka po masło.
|
|
|
![]()
Post
#33
|
|
Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat Czy napisałem że zło wcielone? No to spojrzmy:padło pytanie: Ok, ale dlaczego dziedziczenie to zło na ktore ty odpowiedziales: Bo w większości przypadków jest zbędne , a początkujący OOPowcy wciskają je gdzie się da Oczywiście czasem jest przydatne ale czasem. Czyli potwierdziles teze zapytania. a ze czasem przydatne... Tak czy siak nadal gadasz/gadacie glupoty. Nie wyobrazam sobie OOP bez dziedziczenia. I nie, nie daje tego wszedzie gdzie sie da. Daje wszedzie tam gdzie potrzeba. Do pracy tez nie latam heliktopterem, ale jakby trzeba było kogoś ratowac to i owszem. Wiec heliktopery sa potrzebne (IMG:style_emoticons/default/tongue.gif) |
|
|
![]()
Post
#34
|
|
Grupa: Moderatorzy Postów: 6 072 Pomógł: 861 Dołączył: 10.12.2003 Skąd: Dąbrowa Górnicza ![]() |
Oczywiście czasem jest przydatne ale czasem. Stwierdzenie "czasem X ale czasem" jasno daje do zrozumienia, że zazwyczaj tak nie jest więc może nie wypieraj się teraz tego (IMG:style_emoticons/default/smile.gif) Nie napisałeś, że to zło wcielone (napisał to ~Cysiaczek), ale podpisałeś się pod jego słowami. |
|
|
![]()
Post
#35
|
|
Grupa: Moderatorzy Postów: 4 069 Pomógł: 497 Dołączył: 11.05.2007 Skąd: Warszawa ![]() |
OK. W takim razie rozwinę : dziedziczenie to zło w rękach początkującego OOPowca który lata helikopterem po statek aby dopłynąć do sklepu po masło (IMG:style_emoticons/default/tongue.gif)
|
|
|
![]()
Post
#36
|
|
Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
No to czego na tak ogolne pytanie odpowiadasz tylko o wybranym gronie uzytkownikow i nie zaznaczysz tego dokladnie.... (IMG:style_emoticons/default/winksmiley.jpg) tylko flame sie tu rodzi niepotrzebnie (IMG:style_emoticons/default/winksmiley.jpg)
Wracając do tematu: Normalnie nie uzywam interfejsów. Uzywam ich jedynie w klasach/projektach gdy ktoś będzie mogł coś dopisywać swojego i podpinać pod moje. Interfejs zabezpiecza mnie przed tym, ze ktoś coś skopie w metodach i bedzie na mnie. Przyklad: napisałem klase cache. Do cache mozna podpiąc rozne sterowniki zapisu cache: pliki, baza danych, pamiec. Każdy może napisac wlasne sterowniki jakie mu przyjdą do głowy. Ja jedynie wymagam by implementowaly one moj interfejs - dzieki temu klasa moze bez problemu uzywac cudzysz sterowników - wiem, ze sie nie wywali na zlej nazwie metody czy na zlych argumentach. |
|
|
![]()
Post
#37
|
|
Grupa: Zarejestrowani Postów: 175 Pomógł: 12 Dołączył: 28.06.2007 Skąd: Bytom Ostrzeżenie: (0%) ![]() ![]() |
Wracając do tematu: Uzywam ich jedynie w klasach/projektach gdy ktoś będzie mogł coś dopisywać swojego i podpinać pod moje. Interfejs zabezpiecza mnie przed tym, ze ktoś coś skopie w metodach i bedzie na mnie. Podpisuję się pod tym, interfejsy to pewnego rodzaju drogowskazy, powodują że kod się sam dokumentuje. Chociaż czasem może być drażniące skakanie po plikach. Niektórzy zaczynają pisać systemy od zaplanowania fundamentów - interfejsów, a następnie biorą się za pisanie reszty, pozwala to nie odbiegać od ustalonej wcześniej ścieżki. Mogę też podać pewien przykład implementacji interfejsów: System oparty na pluginach, nie wiadomo kto będzie pisał nowe pluginy. Ale wiadomo że wstrzykując do klasy bazowej plugin wymagamy, aby posiadał pewne metody. Oczywiście można też użyć ReflectionApi, albo jedno i drugie. Co do samego dziedziczenia, to wg mnie trzeba je ograniczać - zmiany w klasie po której dziedziczymy, mogą wymusić zmiany w klasach potomnych. Jeśli system posiada zbyt dużo powiązań między klasami to powstaje "obiektowe spagetti". Ten post edytował plurr 4.09.2009, 13:12:04 |
|
|
![]()
Post
#38
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat No i to jest właśnie ten problem którego chciałem uniknąć. Założyłem temat na Hydeparku, a nie w PHP żeby mi nie tłumaczono co można w PHP a czego nie, bo to mnie zupełnie nie interesuje Tak więc nie traktuje tylko z perspektywy PHP, gdzie bez interface-ów dałoby się objeść.W językach typu Java nie wyobrażam sobie pracy bez interface-ów - głównie dlatego, że same w sobie stanowią one osobny typ. Są one również (tu już można mówić o wszystkich językach obsługujących je) niezwykle przydane w przypadku, gdy programiści tworzą kod dla programistów (to co nospor opisał). Co do "zła w postaci dziedziczenia". Również nie wyobrażam sobie pracy bez niego. A to, że ludzie potrafią źle używać jakiegoś narzędzia to nie argument za tym by uznać narzędzie samo w sobie złym... |
|
|
![]()
Post
#39
|
|
Grupa: Moderatorzy Postów: 4 465 Pomógł: 137 Dołączył: 26.03.2004 Skąd: Gorzów Wlkp. ![]() |
Jeśli nieprecyzyjnie się wyraziłem, to sprostuję. Zgadzam się ze @Spawnmem. Chodzi o to, że większość zastosowanych w praktyce relacji dziedziczenia jest "implementacją złego projektu", a więc "złem wcielonym". Dlatego lepiej wszystkim mówić, że dziedziczenie to ZUO, bo może się 3 razy zastanowią nad relacjami w projekcie.
Nie używam dziedziczenia inaczej jak z klasy abstrakcyjnej. Jeśli już to robię ze zwykłej klasy, to znaczy, że pracuję z czyimś kodem, gdzie nie mam wyboru. Kompozycja jest preferowaną metodą łączenia obiektów, ponieważ jest bardziej elastyczna. Dziedziczenie nie jest elastyczne - jest relacją bardzo sztywną. Prawdopodobnie z powodu nadużywania, Gosling (tak mi się zdaje, że On) powiedział co powiedział. Pozdrawiam |
|
|
![]()
Post
#40
|
|
Grupa: Moderatorzy Postów: 2 921 Pomógł: 269 Dołączył: 11.08.2005 Skąd: 127.0.0.1 ![]() |
Interface jest idealnym przykładem różnicy między teorią, a praktyką.
W teorii interface stanowi punkty wejścia/wyjścia z "black box-a". Blavk box jest tutaj dowolnym tworem, w którym mogą zachodzić różne operacje, o których nie musimy nic wiedzieć. Nas interesuje jedynie w jaki sposób można wykonać operacje na tym pudełku oraz jak pobrać i dostarczyć do niego dane. I tutaj z pomocą przychodzi interface, który nas o tym informuje. W praktyce wszyscy wiemy jak to wygląda. W teorii programowania obiektowego wszystko jest obiektem (czyli posiada jakiś typ). Bardzo często zdarza się, że dany element musi posiadać dwa lub więcej typów. Można to osiągnąć poprzez wielodziedziczenie (mądre głowy zarzuciły ten pomysł, czyli musiał się nie sprawdzić), stworzenie potężnego drzewa zależności (nie muszę chyba pisać jak głupi jest to pomysł) oraz dzięki interface-om. Życiowym przykładem, w którym można wytłumaczyć sens istnienia interface-ów i ich zastosowanie jest operator sumowania. Weźmy taki przykład: x + y gdzie x = 1, a y = 2. Wynikiem takiej operacji będzie 3. Ale skąd ma o tym wiedzieć kompilator/parser? Stąd, że do operatora przekazywane są dwie wartości o typach liczba. Jednak, skąd ten typ się wziął? Wziął się z interface-u, po którym dziedziczy(niejawnie) nasza zmienna. Poza typem liczba, nasza zmienna może dziedziczyć po interface np. sumowalna lub zmiennoprzecinkowa. Operator sprawdzając czy przekazana zmienna posiada jakiś typ, może wykonać stosowne operacje. Mechanizm ten można ostrożnie porównać do przeciążania metod. |
|
|
![]()
Post
#41
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Chyba się mylisz ~batman. Parser/kompilator nic nie musi wiedzieć.
Kod x = 1 y = 2 z = x + y Jest tożsame z Kod x.=(1) y.=(2) z.=(x.+(y)) Przynajmniej w Pythonie i Rubym, wydaje mi się że w większość języków naprawdę obiektowych tak jest. Operatory to są de facto funkcje wbudowane w język. I nie ma żadnego chorego dziedziczenia po interfejsie zmiennoprzecinkowa ( O.o WTF?!?). Po co typ liczby zmiennoprzecinkowej ma dziedziczyć po jakimkolwiek interfejsie skoro taki interfejs, jak już do tego doszliśmy, jest tylko pomocą dla programisty a nie czymś tak ważnym dla samego języka jak np. zmienna, klasa, czy funkcja/metoda. |
|
|
![]()
Post
#42
|
|
Grupa: Moderatorzy Postów: 2 921 Pomógł: 269 Dołączył: 11.08.2005 Skąd: 127.0.0.1 ![]() |
~sztosz pytałeś czysto teoretycznie, abstrahując od konkretnej implementacji (przynajmniej tak to zrozumiałem). Jak to jest w konkretnym kompilatorze/parserze, trzeba już samemu pogrzebać.
A co w takiej sytuacji: x = abc y = 2 z = x + y Co teraz ma zrobić kompilator/parser? Jeśli nie znałby typu (odziedziczonego po interface), wówczas niezłe rzeczy by się działy w pudełkach spod biurka (IMG:style_emoticons/default/winksmiley.jpg) |
|
|
![]()
Post
#43
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
A czemu niby typ ma być dziedziczony po interfejsie?
Kompilator, parser sprawdza czy obiekt x posiada metodę =() i czy argumetnem tej metody może być string (w niektórych językach możliwe jest dodawanie stringów do intów i wtedy nie jawnie te inty są rzutowane na stringi, lub stringi na inty (jeśli te stringi to znaki z zakresu [0-9]), jeśli może to dodaje, jeśli nie to wywala wyjątek. Pisałem że wiem jak to jest w Pythonie i Rubym, bo nie zagłębiałem się w implentacje tego w innych języków. Ty gdzieś przeczytałeś o dziedziczeniu typów podstawowych po interfejsach czy sam to wymyśliłeś? |
|
|
![]()
Post
#44
|
|
Grupa: Moderatorzy Postów: 2 921 Pomógł: 269 Dołączył: 11.08.2005 Skąd: 127.0.0.1 ![]() |
Cytat A czemu niby typ ma być dziedziczony po interfejsie? A dlaczego nie? Interface po to między innymi został stworzony, by dany obiekt mógł mieć kilka typów.Cytat Kompilator, parser sprawdza czy obiekt x posiada metodę =() i czy argumetnem tej metody może być string (w niektórych językach możliwe jest dodawanie stringów do intów i wtedy nie jawnie te inty są rzutowane na stringi, lub stringi na inty (jeśli te stringi to znaki z zakresu [0-9]), jeśli może to dodaje, jeśli nie to wywala wyjątek. Refaktorin mimo swoich niezaprzeczalnych zalet, ma jedną wadę - jest wolny. Znacznie szybciej sprawdzisz typ.Cytat Ty gdzieś przeczytałeś o dziedziczeniu typów podstawowych po interfejsach czy sam to wymyśliłeś? Czytałem takie coś na blogu (źródła nie podam, nie zapisałem). Oczywiście rozważania autora były czysto teoretyczne - tak samo w moim przypadku. W końcu o to Ci chodziło? |
|
|
![]()
Post
#45
|
|
Grupa: Zarejestrowani Postów: 1 415 Pomógł: 117 Dołączył: 7.09.2005 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
batman, jak mniemam chodzi Tobie o to samo na czym opiera się składnia LINQ w .NET. Tak?
edit: przeformułowanie Ten post edytował LBO 5.09.2009, 17:58:28 |
|
|
![]()
Post
#46
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat skoro taki interfejs, jak już do tego doszliśmy, jest tylko pomocą dla programisty Gdzie doszliśmy do takiego wniosku? Sam napisałem, że np. w Javie właściwie bez nich nie da się obejść - a jestem tego pewien, mimo iż nie mogę powiedzieć, że mam w tym języku jakieś doświadczenie. |
|
|
![]()
Post
#47
|
|
Grupa: Moderatorzy Postów: 2 921 Pomógł: 269 Dołączył: 11.08.2005 Skąd: 127.0.0.1 ![]() |
|
|
|
![]()
Post
#48
|
|
Grupa: Zarejestrowani Postów: 1 415 Pomógł: 117 Dołączył: 7.09.2005 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Nie. Chodzi mi tylko i wyłącznie o teorię. Bez żadnej implementacji. Z teorią to tu daleko nie zajdziesz. Podstawowe LINQ opiera się całkowicie na interfejsach i tyle - każda implementacja działa zupełnie inaczej, więc nie ma co tworzyć klasy bazowej/abstrakcyjnej). +1 dla interfejsów. Natomiast to o czym ty piszesz, czyli operatory w językach kompilowanych nie opierają się na interfejsach tylko na metodach, które można dopisać do własnych obiektów lub przeciążać. |
|
|
![]()
Post
#49
|
|
Grupa: Moderatorzy Postów: 2 921 Pomógł: 269 Dołączył: 11.08.2005 Skąd: 127.0.0.1 ![]() |
LBO
Cytat Ja tylko niosę pomoc (IMG:style_emoticons/default/winksmiley.jpg) Jeśli chciałbym pisać o .NET, to pisałbym w jego kontekście. Autor tematu prosił o wyjaśnienie po co są interface-y, a nie jak działają w konkretnym języku. Przykład z operatorem wydawał mi się najbliższy sercu programisty, więc go wykorzystałem. Nie chodziło mi o zanurzanie się w teorię przeciążania operatorów, LINQ, czy w konkretną implementację interface-ów. Moje rozważania są czysto teoretyczne i mają tyle wspólnego z rzeczywistością, co UML - z resztą napisałem to w moim pierwszym poście w tym temacie. |
|
|
![]()
Post
#50
|
|
Grupa: Zarejestrowani Postów: 1 415 Pomógł: 117 Dołączył: 7.09.2005 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Przepraszam. (IMG:style_emoticons/default/smile.gif) Jakby na to nie patrzeć czysto teoretycznie LINQ opiera się na wbudowanych w język operatorach i interfejsach z nich korzystających, o! Jest doskonałym przykładem na ich (interfejsów) poparcie ;P Jedyny szkopuł w nieadekwatności do niedorobionej obiektówki PHP (IMG:style_emoticons/default/sad.gif) edit: doprecyzowanie Ten post edytował LBO 5.09.2009, 18:33:08 |
|
|
![]()
Post
#51
|
|
Grupa: Moderatorzy Postów: 2 921 Pomógł: 269 Dołączył: 11.08.2005 Skąd: 127.0.0.1 ![]() |
Niestety nie poznałem LINQ na tyle, by móc prowadzić dyskusję z jego wykorzystaniem na takim poziomie abstrakcji (IMG:style_emoticons/default/winksmiley.jpg) Pozostawiam pole osobie, która wie o czym pisze (IMG:style_emoticons/default/winksmiley.jpg)
Cytat Jedyny szkopuł w nieadekwatności do niedorobionej obiektówki PHP Gdyby się dłużej zastanowić, to z językami obiektowymi jest tak jak z przeglądarkami internetowymi. Niby robią to samo, ale każdy z nich inaczej implementuje standardy. I pewnie stąd są problemy w odbiorze niektórych zagadnień związanych z obiektówką. |
|
|
![]()
Post
#52
|
|
Grupa: Zarejestrowani Postów: 1 415 Pomógł: 117 Dołączył: 7.09.2005 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Gdyby się dłużej zastanowić, to z językami obiektowymi jest tak jak z przeglądarkami internetowymi. Niby robią to samo, ale każdy z nich inaczej implementuje standardy. I pewnie stąd są problemy w odbiorze niektórych zagadnień związanych z obiektówką. Coś w tym jest. Abstrahując od wyboru gdzie użyć interfejsu, a gdzie klasy bazowej (i nawiązując do wypowiedzi w tym wątku) to programując języku, który posiada wielokrotne dziedziczenie nie bawiłbym się w interfejsy. Działa to też w drugą stronę - nie zrezygnuje z nich w PHP ze względu na korzyści jakie ze sobą niosą. Druga sprawa, że wielokrotne dziedziczenie ma tyle samo wrogów, co zwolenników. Ja jestem wrogiem. Interfejsy mimo, że niełatwe w obsłudze mają swoje zalety i trudniej nimi napsuć |
|
|
![]()
Post
#53
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Autor tematu prosił o wyjaśnienie po co są interface-y, a nie jak działają w konkretnym języku. Przykład z operatorem wydawał mi się najbliższy sercu programisty, więc go wykorzystałem Ok, ale akurat typ int dziedziczący po interfejsie dodawanie jest dla mnie poronionym pomysłem i to już tak zupełnie. Pisząc kompilator/interpreter ostatnia rzecz której nam potrzeba to nadmiarowy kod który niczego nam nie daje. Co z tego że int będzie implentował interfejs dodawanie, skoro tak czy inaczej bez względu czy implentuje ten interfejs czy nie musi posiadać metodę dodawanie? Cytat(batman @ 5.09.2009) Refaktorin mimo swoich niezaprzeczalnych zalet, ma jedną wadę - jest wolny. Znacznie szybciej sprawdzisz typ. Nie mam pojęcia co to "Refaktorin", zakładam że to czysta literówka i masz na myśli "Refactoring", ale wtedy zupełnie nie wiem co masz na myśli pisząc że jest wolny? I jak to się ma do tematu interfejsów? I co to znaczy że szybsze jest sprawdzanie typu od Refactoring? Serio zdębiałem. Cytat(batman @ 5.09.2009) Interface po to między innymi został stworzony, by dany obiekt mógł mieć kilka typów. Interface nie zmienia i nie dodaje typu obiektu, z tego co ja się orientuje to obiekt może być tylko jednego typu. Patrząc najprościej obekt "X" nie może być typu INT oraz STRING. Interface tylko i wyłącznie wymusza metody. Jeżeli mamy interface "Zapisz przekazane dane" i mamy 2 klasy które implentują ten interfejs jedną XML (zapisuje w XML), drugą DB (zapisuje w bazie danych), to czy obiekt XML będzie typu XML i "Zapisz przekazane dane" a drugi będzie typu DB i "Zapisz przekazane dane"? Wywracasz mój świat do góry nogami swoimi postami :/ |
|
|
![]()
Post
#54
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Obiekt new Dog() jest typu: Dog, Animal, Moveable, BlahBlah. A.. no i jeszcze Object. (IMG:style_emoticons/default/winksmiley.jpg) Interface-y mogą stanowić osobny, niezależny typ. Ten post edytował Crozin 5.09.2009, 22:55:39 |
|
|
![]()
Post
#55
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Czy na pewno to ze coś implentuje jakiś interfejs sprawia że obiekt staje się typu klasy której jest obiektem + interfejsów które implentuje? A jeśli klasa pies dziedziczy po ssak, to czy obiekt klasy pies jest typu pies oraz ssak?
Czy na pewno to ze coś implentuje jakiś interfejs sprawia że obiekt staje się typu klasy której jest obiektem + interfejsów które implentuje i klass po których dziedziczy? |
|
|
![]()
Post
#56
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Tak, ponieważ Pies dziedzicząc po Ssak otrzymuje jego pełen publiczny interface. Tak więc na obiekcie typu Pies można wykonać dokładnie takie same operacje co na obiekcie Ssak. Różnica jest taka, że pies jako bardziej wyspecjalizowany obiekt może jakąś konkretną metodę realizować inaczej, ale sygnatura tej metody pozostaje niezmienna - tj. interface się nie zmienia. Pies może też realizować metody specyficzne tylko dla Pies, ale mamy 100% że możemy na nim operować jak na Ssak.
Z interface-ami jest dokładnie tak samo.
|
|
|
![]()
Post
#57
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
OK, zwracam więc honor, miałem zupełnie inne wyobrażenie o typach.
|
|
|
![]()
Post
#58
|
|
Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
(odpowiedz na ost. 2 strony postow)
@sztosz Cytat Cytat A co w takiej sytuacji: x = abc y = 2 z = x + y Co teraz ma zrobić kompilator/parser? Jeśli nie znałby typu (odziedziczonego po interface), wówczas niezłe rzeczy by się działy w pudełkach spod biurka Kompilator, parser sprawdza czy obiekt x posiada metodę =() i czy argumetnem tej metody może być string 1. Odroznij najpierw moment kompilacji od momentu uruchomienia. 2. W statycznych jezykach (java, c,..) w momencie KOMPILACJI kompilator musi wiedziec czy zmienna "x" ma metode "+". Sprawdzane jest to po typie zmiennej. Deklarujesz "x" jako 'PlusatorInterface x', ktory to interfejs posiada metode "+" i wszystko jest ok 3. Dla dynamicznych jezykow (Ruby, Python, PHP,...), sprawdzane jest czy OBIEKT! (nie zmienna i jej typ) przypisany do "x" posiada metode "+". To czy uzylismy tu interfejsu nie ma znaczenia, wazne jest tylko posiadanie metody. Dlatego dla tego typu jezykow intefejsy sa stworzone bardziej w celu dokumentacji, przedstawienia projektu fragmentu systemu, pokazaniu czemu te N klas ma takie same metody, niz sa potrzebne do uruchomienia kodu. Skad sie wziely interfejsy - bylo mowione 100 razy - zrezygnowano z wielodziedziczenia, autorzy Javy uzali je za ZLO, i zaproponowali interfejsy (chyba oni byli pierwsi). No i interfejsy sa konieczne w jezykach javo podobnych, ktora nie jest dynamiczna jak php, ruby, python - w ktorych to interfejsy maja mniejsze znaczeni. Cytat Interface nie zmienia i nie dodaje typu obiektu, z tego co ja się orientuje to obiekt może być tylko jednego typu. sztosz, nie obraz sie ale poucz sie javy czy c#. Chociazby podstaw bo z tego co widze to posiadasz znajomosc jedynie dynamicznych jezykow, i pewne rzeczy ci trudniej pojac. Cytat Czy na pewno to ze coś implentuje jakiś interfejs sprawia że obiekt staje się typu klasy której jest obiektem + interfejsów które implentuje i klass po których dziedziczy? Tak. Kod class Bubel extends Something implements Countable {...}
Bubel b = new Bubel(); b.bubluj(); // ZMIENNA b jest typu Bubel, na przypisana instancje Bubel i mozesz na niej uzywac metod zaimplementowanych przez ta klase Countable c = b; // tutaj przypisales do ZMIENNEJ typu Countable ten sam obiekt, klasy Bubel. Ale zmienna ma typ Countable, wiec uzyjesz TYLKO tych metod ktore posiada ten interfejs. System.out.println( c.count() ); |
|
|
![]()
Post
#59
|
|
Grupa: Zarejestrowani Postów: 1 873 Pomógł: 152 Dołączył: 9.04.2006 Skąd: Berlin Ostrzeżenie: (0%) ![]() ![]() |
Najlepszy przykład podał właśnie Crozin. W Thinking in java jest to pięknie pokazane na przykładzie zwierzaków.
Intrefejs określa jakie metody musisz użyć, np jak wyobrażałbyś sobie stworzenie for each dla własnej klasy? (IMG:style_emoticons/default/smile.gif) Przecież jak dajesz
kompilator musi wiedzieć po czym ma iterować i czy w ogóle może iterować. implements Iterable i klasa kolejna implements Iterator załatwiają sprawę. |
|
|
![]()
Post
#60
|
|
Grupa: Zarejestrowani Postów: 866 Pomógł: 32 Dołączył: 2.06.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Mi się wydawało zawsze że można iterować po czymkolwiek (w rozumienie obiekcie) co posiada metody do iterowania po tym czymś. Np w rubym, jeśli obiekt ma odpowiednio zaimplentowaną metodę each to można używać jej jak iteratora w "typach wbudowane", z times jest podobnie, czy upto. W pythonie masz np. __iter__()
~dr_bonzo słusznie napisał: "sztosz, nie obraz sie ale poucz sie javy czy c#. Chociazby podstaw bo z tego co widze to posiadasz znajomosc jedynie dynamicznych jezykow, i pewne rzeczy ci trudniej pojac." Muszę się pobawić więcej Javą, wtedy zapewne będę inaczej na to wszystko patrzył (IMG:style_emoticons/default/winksmiley.jpg) |
|
|
![]()
Post
#61
|
|
Grupa: Zarejestrowani Postów: 175 Pomógł: 12 Dołączył: 28.06.2007 Skąd: Bytom Ostrzeżenie: (0%) ![]() ![]() |
Nasunęła mi się jeszcze jedna myśl, a propos interfejsów (i nie tylko) - mianowicie: "Wymyślanie koła na nowo".
Co prawda w javie piszę dopiero od paru miesięcy, ale zauważyłem, że każde rozwiązanie jest w pewien sposób udokumentowane np. odpowiednim interfejsem/abstraktem etc. Pisząc tam jakąś klasę, nie skupiam się nad tworzeniem całego drzewa począwszy od Object, ale wykorzystuje już to co tam jest, co mi język dostarcza. W phpie zaś, niby mamy SPL, ale jest ono wg mnie dosyć ubogie. Można też powiedzieć, że ile programistów, tyle rozwiązań dotyczących jednego problemu. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 16.09.2025 - 16:18 |