Kedan
11.05.2009, 11:28:38
Mam zależność tego typu:
<?php
class myObject{
//...
}
class myModule extends myObject {
//....
}
class myModuleExt extends myModule {
//....
}
?>
ale do tego mam zależność:
<?php
class myConcreteModule extends myModule {
//...
}
// i tu pojawia się problem
class myConcreteModuleExt extends myModuleExt, myConcreteModule {
//...
}
?>
Od jakiegoś czasu główkuję jak to rozwiązać, ale nic sensownego nie przychodzi mi do głowy.
phpion
11.05.2009, 11:48:03
<?php
class myConcreteModule extends myModuleExt {
//...
}
class myConcreteModuleExt extends myConcreteModule {
//...
}
?>
Kedan
11.05.2009, 12:05:27
Nie o to chodzi.
myConcreteModule ma posiadać tylko i wyłącznie bazową funkcjonalność (myModule) + jakąś własną - unikalną.
myConcreteModuleExt ma posiadać funkcjonalność rozszerzoną (myModuleExt + myModule). unikalną bazową (myConcreteModule) i dodawać własną unikalną rozszerzoną.
Trochę to zakręcone, ale mam nadzieję że sa się to przeprojektować żeby wyglądało sensownie.
Od razu uprzedzam ludzi piszących o interfejsach: nic mi po nich, bo nie mam zamiaru przy każdej klasie definiować wszystkich metod na nowo.
marcio
11.05.2009, 12:29:42
A klasy abstrakcyjne mozesz uzyc jak interfejsy tylko ze mozesz odrazu implementowac w niej metody.
batman
11.05.2009, 12:39:11
Cytat(marcio @ 11.05.2009, 13:29:42 )

A klasy abstrakcyjne mozesz uzyc jak interfejsy tylko ze mozesz odrazu implementowac w niej metody.
Nie może, ponieważ występuje ten sam problem co z klasami nieabstrakcyjnymi - nie można dziedziczyć po więcej niż jednej klasie.
~KedanNiestety w PHP nie ma rozwiązania Twojego problemu. Pozostaje Ci zmiana założeń lub kombinowanie z przekazywaniem pomocniczego obiektu między klasami.
Kedan
11.05.2009, 13:48:53
Ostatecznie wymyśliłem coś takiego:
<?php
class myObj{}
class myModule extends myObj{
public function Foo(){
}
public function Bar(){
}
}
class myModuleEx extends myObj{
protected $_module;
function __construct(){
$this->_module = new myModule();
}
public function __call($name_,$args_=null){
if(!method_exists($this,$name_)&&(method_exists($this->_module,$name_))){
$this->_module->$name_($args_);
}
}
}
class myConcreteModule extends myModule{
public function Zip(){
}
}
class myConcreteModuleEx extends myModuleEx{
function __construct(){
$this->_module = new myConcreteModule();
}
public function Doo(){
}
}
$c = new myConcreteModuleEx();
$c->Zip();
?>
Niby działa, ale pewnie jeszcze parę warunków trzeba będzie dopisać i dopiero przetestować w boju.
okitoki
11.05.2009, 15:26:58
takie bajerki to C++ nam serwuje
interface w php to porażka, nie wiem dlaczego, ale na kilka razy miałem z nimi problem, bo jakiś serwer chociaż miał PHP5 wywalał mi błędy na nich. przez swoją głupotę musiałem potem przerabiać wiele bibliotek, a dokładniej usuwać wszystkie informacje o interfejsach.
może wiecie dlaczego się tak mogło dziać
Kedan
11.05.2009, 15:48:26
Cytat
takie bajerki to C++ nam serwuje
Wiem, tylko pewnie jeszcze troche czasu minie zanim bede serwisy w C++ pisał

Co do interfejsów, może jak implementowałeś kilka w danej klasie to może zapomniałeś zdefiniować jakąś metodę. A jak jeszcze po tej klasie dziedziczyłeś to już w ogóle kiszka. IMO interfejsy są ogólnie be. Tak jak singletony
okitoki
11.05.2009, 18:42:48
Cytat(Kedan @ 11.05.2009, 16:48:26 )

Wiem, tylko pewnie jeszcze troche czasu minie zanim bede serwisy w C++ pisał

Co do interfejsów, może jak implementowałeś kilka w danej klasie to może zapomniałeś zdefiniować jakąś metodę. A jak jeszcze po tej klasie dziedziczyłeś to już w ogóle kiszka. IMO interfejsy są ogólnie be. Tak jak singletony

właśnie nie bo by mi to nie działało, pisałem dość wielki projekt dla bigstara i tam właśnie się z tym spotkałem, ja wtedy u siebie na kompie miałem zainstalowany taki gotowiec, serwer krasnala, i właśnie mi wszystko hulało, jak to przegrałem na wewnętrzny serwer w BS to wszystko padło, i to na błędach krytycznych. jak usunąłem cały wpis o interfejsach to zaczęło działać, aha. O metodę krzyczał, a tam mu się sama deklaracja interfejsu nie podobała.
Żeby próbować odpalać interfejsy na PHP4 i złościć się, że nie działają, to trzeba być naprawdę zdolnym... jak Ci niby mają zadziałać, jak PHP4 ich nie obsługuje? Inerfejsy od wielu lat świetnie się mają chociażby w Javie, skąd zostały żywcem zerżnięte do PHP. Wykorzystuje je wiele projektów i jakoś nikt nie narzeka.
Wielokrotne dziedziczenie jest dość niebezpieczne z kilku powodów. Po pierwsze, nie oddziela implementacji od publicznego interfejsu - da się przez to stworzyć hierarchię klas, gdzie zmiana implementacji może wymuszać zmianę interfejsu lub zmuszać do nieprawidłowego użycia obiektów. Innymi słowy, trzeba znać bardzo dobrze wewnętrzne mechanizmy języka i przestrzegać ściśle dyscypliny. Kolejny mój zarzut przeciwko wielokrotnemu dziedziczeniu to sprawianie złudnego wrażenia, że jest ono potrzebne, podczas gdy sytuacje takie są baaaaaaaardzo rzadkie i w większości wynikają po prostu z popełnionych błędów projektowych. Nie bez powodu w Javie nie zdecydowano się na wprowadzenie czegoś takiego.
Kedan -> Twój problem może być bez trudu rozwiązany np. przez użycie kompozycji, albo przemyślenie, czy naprawdę musi to być w ten sposób właśnie robione... dokładną decyzję musisz podjąć sam, ponieważ to jest Twój kod i powinieneś najlepiej wiedzieć, co on ma odzwierciedlać. Przemyśl to, co napisałem. Tysiące, jeśli nie dziesiątki tysięcy projektów doskonale sobie bez wielokrotnego dziedziczenia radzą i mają się świetnie.
Spawnm
11.05.2009, 20:45:41
warto imho przyjrzeć się :: , czyli klasa::funkcja() bez dziedziczenia
okitoki
11.05.2009, 21:37:00
Cytat(Zyx @ 11.05.2009, 21:35:43 )

Żeby próbować odpalać interfejsy na PHP4 i złościć się, że nie działają, to trzeba być naprawdę zdolnym... jak Ci niby mają zadziałać, jak PHP4 ich nie obsługuje? Inerfejsy od wielu lat świetnie się mają chociażby w Javie, skąd zostały żywcem zerżnięte do PHP. Wykorzystuje je wiele projektów i jakoś nikt nie narzeka.
oj zyx może tobie kupili peceta teraz na urodziny, a ja niestety nie programuje od wczoraj. na php4 ten projekt by poszedł dopiero po totalnej przeróbce gdyż był cały napisany w OOP. A jak piszesz takie bzdury, to znaczy że ty w ogóle nie wiesz jak wyglądała obiektowość w PHP4, a raczej jej zarys, bo do obiektowości jej sporo brakowało.
Cytat
O metodę krzyczał, a tam mu się sama deklaracja interfejsu nie podobała.
Deklaracja działającego w jednym miejscu interfejsu może się nie podobać tylko i wyłącznie PHP4 oraz starszym. To, że projekt był w obiektówce, jeszcze nie jest wyznacznikiem, że był pisany pod PHP5. Wprawdzie obiektówka była w czwórce marna, ale była i się z niej chcąc nie chcąc korzystało. Powtarzam: mnóstwo projektów sobie znakomicie z interfejsami radzi i jakoś bugtrackera PHP nie zalewa fala żalu o tym, jak to się kod działający na jednym serwerze totalnie sypie na innym.
A wycieczki personalne możesz sobie darować, chyba że bardzo lubisz bliskie spotkania trzeciego stopnia z moderatorami.
Kedan
11.05.2009, 23:47:12
@Spawnm
Metody statyczne nie są złe, ale trochę nieeleganckie. Zazwyczaj stosuję je gdy potrzebuję coś "na szybko" albo gdy dana metoda jest tak podstawowa, że praktycznie każdy obiekt w systemie powinien ją posiadać (choć staram się tego unikać i kiedy mogę stosuję dziedziczenie);
@Zyx
No właśnie przy pomocy kompozycji rozwiązałem to w ostatnim kodzie jaki podałem

Myk tylko polega na tym, że obiekt sprawdza czy posiada daną metotę i jeśli nie - wywołuje metodę swojej składowej. Niestety możliwe jest to tylko dla metod publicznych, więc wszystkie metody chronione trzeba 'cofnąć' o jedno pokolenie wyżej - do myObj. W przypadku jaki podałem kazda z klas dodaje swoje trzy grosze do funkcjonalności; chodzi o ostateczne stworzenie obiektu posiadającego, w zależności od uprawnień, taki a nie inny zestaw metod, przy czym część z nich jest wszędzie taka sama, część ma być nadpisana a część całkowicie unikalna. Pewnie uda mi się jeszcze coś wyczarować z jakimś wzorcem projektowym, jakaś fabryka czy cuś...
Co do interfejsów - częściej mam potrzebę stosowania właśnie wielokrotnego dziedziczenia (takie mi zboczenie po C++ zostało) - jest to IMO o wiele bardziej naturalna 'droga' i OOP dużo traci rezygnując z tego rozwiązania. Wiem że jest mnóstwo projektów radzących sobie bez MI, ale pewnie tylko dlatego że nie ma innego wyjścia

(specyfika języka).
okitoki
12.05.2009, 05:27:42
Cytat(Zyx @ 11.05.2009, 23:31:10 )

Deklaracja działającego w jednym miejscu interfejsu może się nie podobać tylko i wyłącznie PHP4 oraz starszym. To, że projekt był w obiektówce, jeszcze nie jest wyznacznikiem, że był pisany pod PHP5. Wprawdzie obiektówka była w czwórce marna, ale była i się z niej chcąc nie chcąc korzystało. Powtarzam: mnóstwo projektów sobie znakomicie z interfejsami radzi i jakoś bugtrackera PHP nie zalewa fala żalu o tym, jak to się kod działający na jednym serwerze totalnie sypie na innym.
A wycieczki personalne możesz sobie darować, chyba że bardzo lubisz bliskie spotkania trzeciego stopnia z moderatorami.
aż strach się bać
nospor
12.05.2009, 06:37:11
@okitoki zyx jedynie napisał, ze w php4 nie bylo interfejsow. Moze ty i programujesz od kilku lat, ale z czytaniem ze zrozumieniem masz niesamowite problemy. Az strach sie bac jak ty czytasz specyfikacje projektow.
Cytat
aż strach się bać
Tego typu posty oraz wycieczki personalne nie są mile widziane na forum, wiec przystopuj.
okitoki
12.05.2009, 17:10:41
nie zupełnie, tak jak piszesz, bo stwierdził fakt że próbowałem to odpalić na PHP4, jak by tak było to bym nie pytał, co mogło być powodem, bo w PHP siedzę od wersji 3
Cytat(Zyx @ 11.05.2009, 21:35:43 )

Żeby próbować odpalać interfejsy na PHP4 i złościć się, że nie działają, to trzeba być naprawdę zdolnym... jak Ci niby mają zadziałać, jak PHP4 ich nie obsługuje? Inerfejsy od wielu lat świetnie się mają chociażby w Javie, skąd zostały żywcem zerżnięte do PHP. Wykorzystuje je wiele projektów i jakoś nikt nie narzeka.
Spawnm
12.05.2009, 17:14:01
skoro mowa o Wielodziedziczeniu , to mógł by mi ktoś powiedzieć jak się je robi za pomocą interfejsu ?
bo na phpedi pisze że można
marcio
12.05.2009, 17:22:54
Chodzi chyba o to ze np w jakies klasie mozesz uzyc 1 lub wiecej interfejsow potem np po tej klasie dziedziczysz i mozesz sobie dodac nowe interjesy poprostu slowo implements nie ma ograniczen jak extends ze jesli damy wiecej niz 1 interfejs nie zadziala, tak mi sie wydaje ze o to chodzi w praktyce nie wiem jak z tym jest
plurr
12.05.2009, 17:36:53
Cytat(Spawnm @ 12.05.2009, 18:14:01 )

skoro mowa o Wielodziedziczeniu , to mógł by mi ktoś powiedzieć jak się je robi za pomocą interfejsu ?
bo na phpedi pisze że można

mozesz implementowac wiecej interfejsow, tym samym wymuszać na klasie pewne zachowania.
Listing na przykladize wzorca registry -
http://athlan.pl/code/RegistryExtended Jak sam autor tego listingu napisał, implementuje interfejsy:
"Iterator
ArrayAccess (na potrzeby poruszania się po instancji jak po tablicy)
Countable (aby łatwo otrzymać liczbę przechowywanych danych)
Serializable (żeby można było zaserializować i odserializować instancję obiektu)"Ogolnie rzecz biorac, wiele osob twierdzi ze dziedziczenie jest zle, po pewnych doswiadczeniach rowniez ja zgadzam sie z ta opinia.
dziedziczenie < kompozycja http://art-of-software.blogspot.com/2008/0...-telefonie.html
rzymek01
12.05.2009, 18:03:23
Cytat(plurr @ 12.05.2009, 18:36:53 )

Ogolnie rzecz biorac, wiele osob twierdzi ze dziedziczenie jest zle, po pewnych doswiadczeniach rowniez ja zgadzam sie z ta opinia. dziedziczenie < kompozycja
oryginalna opinia, odnosisz ją tylko do PHP czy tak ogólnie?
plurr
12.05.2009, 18:06:10
Cytat(rzymek01 @ 12.05.2009, 19:03:23 )

oryginalna opinia, odnosisz ją tylko do PHP czy tak ogólnie?

ogolnie. Niezbyt oryginalna, spotykam sie z ta opinia dosyc czesto.
marcio
12.05.2009, 18:40:51
Cytat
ogolnie. Niezbyt oryginalna, spotykam sie z ta opinia dosyc czesto.
Zgadzam sie pionerem w OOp nie jestem ale tez czesto spotykam sie z taka opinia a jak nie wierzysz wystarczy poczytac watki o opini wyrzucienia wielodziedziczenia z takich jezykow jak Java,Delphi,C# ktore mozna jednak uzyc w Cpp.
http://forum.gamedev.pl/index.php?action=p...ge;topic=9419.0To jeden z kilku tematow.
rzymek01
12.05.2009, 19:07:40
jeszcze raz przytoczę:
Cytat
Ogolnie rzecz biorac, wiele osob twierdzi ze dziedziczenie jest zle (...)
nie ma tu nic mowy o wielodziedziczeniu, czyli koledze @plurr chodziło o to, że kazde dziedziczenie jest złe, z czym się nie zgadzam, bo wg mnie polepsza czytelność kodu, a także niektóre rzeczy wręcz umożliwia bądź wybitnie ułatwia

jesli natomiast chodziło tylko o wielodziedziczenie to się zgadzam, chociaż parę razy skorzystałem z dziedziczenia z dwóch klasach, ale było to logicznie uzasadnione
nieraczek
12.05.2009, 19:13:58
Dziedziczenie złe ? Jeśli nie dziedziczenie to co ? Złe to są wskaźniki w c++
rzymek01
12.05.2009, 19:15:00
Cytat(nieraczek @ 12.05.2009, 20:13:58 )

Złe to są wskaźniki w c++

a jak dla mnie ulubiona rzecz, i co ?
plurr
12.05.2009, 19:18:02
chodzi mi o samo dziedziczenie - jest be. lepiej wkomponowac obiekt w klase niz uzywac dziedziczenia gdzie popadnie. Już nie wspomne o dziwactwach typu: szablon do PDF po klasie smarty, albo w celu przyslonienia jednej metody.
Niektorzy ludzie zachlysna sie OOP i dziedzicza wszystko co popadnie, a z punktu architektonicznego wyglada to gorzej niz zle (pewnie pod katem wydajnosci takze ma to jakies znaczenie).
W linku, który podałem wcześniej, bardzo fajnie sa opisane te wszystkie wady dziedziczenia.
okitoki
12.05.2009, 21:08:07
Cytat(nieraczek @ 12.05.2009, 20:13:58 )

Dziedziczenie złe ? Jeśli nie dziedziczenie to co ? Złe to są wskaźniki w c++

wszystko jest kiepskie, jak jest trudne i się tego nie rozumie, wskaźniki są super, jak się nad nimi panuje, no niestety c++ to już nie jest php, tam jak się coś zawali, a szczególnie na wskaźnikach, to nieraz jest ciężko dojść gdzie jest problem, tu w php co najwyżej nie będzie nam działać fragment kodu, ale łatwo to idzie naprawić
Cytat(plurr @ 12.05.2009, 20:18:02 )

chodzi mi o samo dziedziczenie - jest be. lepiej wkomponowac obiekt w klase niz uzywac dziedziczenia gdzie popadnie. Już nie wspomne o dziwactwach typu: szablon do PDF po klasie smarty, albo w celu przyslonienia jednej metody.
Niektorzy ludzie zachlysna sie OOP i dziedzicza wszystko co popadnie, a z punktu architektonicznego wyglada to gorzej niz zle (pewnie pod katem wydajnosci takze ma to jakies znaczenie).
W linku, który podałem wcześniej, bardzo fajnie sa opisane te wszystkie wady dziedziczenia.
no wiesz jak coś jest źle napisane, to faktycznie dziedziczenie to kiepski pomysł, ale z drugiej strony, jak masz obiekt np koło samochodowe, i chcesz do niego dodać wentyl, to poco pisać na nowo, opisywać koło z wentylem, jak można z dziedziczyć koło i dodać do niego wentyl
pyro
12.05.2009, 21:11:24
Cytat(plurr @ 12.05.2009, 20:18:02 )

chodzi mi o samo dziedziczenie - jest be.
Porób trochę rzeczy w OOP i dopiero się wypowiadaj
Spawnm
12.05.2009, 21:15:29
jest be puki nie chcesz klasą admin odziedziczyć klasy user , mod, mysql

wtedy trzeba kombinować z :: ew w __construct dawać $this->mod=new mod();
a tak to by się dało tylko extends i po sprawie
ale mamy :: i cieszmy się z tego
plurr
12.05.2009, 21:35:55
Cytat(pyro @ 12.05.2009, 22:11:24 )

Porób trochę rzeczy w OOP i dopiero się wypowiadaj

Później musimy poprawiać kod takich "pseudo-doswiadczonych-programistów" jak Ty
Ucz się architerktury kolego, nie tylko "extends" i do boju.
pyro
12.05.2009, 21:42:51
Cytat(plurr @ 12.05.2009, 22:35:55 )

Później musimy poprawiać kod takich "pseudo-doswiadczonych-programistów" jak Ty
Ucz się architerktury kolego, nie tylko "extends" i do boju.
i Ty mi to mówisz hipokryto? Jak się nie umie wykorzystać dziedziczenia to kod jest zły. Widać Ty nie znasz jego założeń. Jak się nauczysz korzystać z sensem z dziedziczenia to dopiero pisz, a nie szerzysz hipokryzję. Według Ciebie wszystkie większe projekty jak (o ile dobrze pamiętam) chociażby skrypt forum, na którym się aktualnie znajdujemy jest zły, bo korzysta z dziedziczenia i dziedziczenie zostało niepotrzebnie zaimplementowane przez programistów, którym wiedzą nie sięgasz do podeszwy, tylko Ty masz rację i Twoje bzdurne założenia?
Jeśli tak to niestety nie mamy o czym gadać
Crozin
12.05.2009, 21:44:57
@Spawnm: co mają do tego metody statyczne? Nie za bardzo sobie mogę wyobrazić. Poza tym można przecież przekazać już istniejący obiekt do nowo tworzonego czy to poprzez przekazanie go w parametrze czy odczytanie z np. rejestru.
Cytat
chodzi mi o samo dziedziczenie - jest be.
Chodzi co o to, że w ogóle idea dziedziczenia jest be, hierarchia dziedziczenia jest be, wielokrotne dziedziczenie jest be czy nadmierne dziedziczenie jest be?
plurr
12.05.2009, 21:46:33
Cytat(pyro @ 12.05.2009, 22:42:51 )

....
przeczytaj ze zrozumieniem moje poprzednie posty, a pozniej pisz kolejne bzdety.
pyro
12.05.2009, 21:48:05
Cytat(plurr @ 12.05.2009, 22:46:33 )

przeczytaj ze zrozumieniem moje poprzednie posty, a pozniej pisz kolejne bzdety.
Sam przeczytaj swoje posty, bo widać sam nie wiesz co piszesz.
plurr
12.05.2009, 21:49:57
Cytat(Crozin @ 12.05.2009, 22:44:57 )

Chodzi co o to, że w ogóle idea dziedziczenia jest be, hierarchia dziedziczenia jest be, wielokrotne dziedziczenie jest be czy nadmierne dziedziczenie jest be?
Chodzi mi o to, że lepiej uzywac kompozycji/agregacji jesli mozna niz zaraz odwolywac sie do dziedziczenia. O wielokrotnym dizedziczeniu to wszyscy wiemy, chociazby dlatego nie zostalo to wprowadzone do Javy.
Ciekawostka:
http://www.javaworld.com/javaworld/jw-08-2...01-toolbox.html
Przeczytajcie sobie wszyscy najlepiej jakąś książkę o wzorcach projektowych. Dziedziczenie jest dobre ale nie we wszystkim, a właściwie to większość osób je nadużywa często.
Przykład gry szachy.
1. Sposób: Można zrobić sobie klasę ruch i każda figura, pionek po niej dziedziczy. W zależności od typu figury/pionka oraz ruchu jaki się chce wykonać metoda mogePrzejsc zwraca true, false.
2. Sposób: Można tez zaprojektować interface Ruch, dla każdego pionka/figury tworzymy odpowiednie klasy implementujace Ruch. Każdy pionek/figura posiada zmienna obiektowa mogePrzejsc (domyślnie interface Ruch), do której sobie przypisujemy odpowiednia klasę w zależności od rodzaju figury.
Mam nadzieje że każdy zrozumie ten przykład. Teraz powiedzcie mi proszę co jest łatwiej rozbudować o nowe ruchy ?
Zaleta 2 sposobu ? Dodajemy nową funkcjonalność bez zmiany starej, etc, etc..
nieraczek
13.05.2009, 08:54:52
Nie wiem co poniektórym podoba się we wskaźnikach w c++, one wszystko tylko komplikują, referencje są znacznie lepsze, w c# i javie można powiedzieć całkowicie zrezygnowano ze wskaźników, a przynajmniej ich używanie nie jest zalecane.
Crozin
13.05.2009, 09:27:34
Cytat
1. Sposób: Można zrobić sobie klasę ruch i każda figura, pionek po niej dziedziczy. W zależności od typu figury/pionka oraz ruchu jaki się chce wykonać metoda mogePrzejsc zwraca true, false.
Nie, nie można tak zrobić, ponieważ nie mogę sobie wyobrazić w jaki sposób figura jest rozwinięciem ruchu. Błędny przykład dziedziczenia podałeś.
Natomiast bardzo łatwo jest mi sobie wyobrazić w jaki sposób klasy Król, Hetman, Wieża, Skoczek czy Goniec dziedziczą po abstrakcyjnej klasie Pionek (wybaczcie, nie wiem jaka jest ogólna nazwa dla wyżej wymienionych).
Nieraczek -> mała uwaga, że dyskusja nie dotyczy wskaźników, tylko wielokrotnego dziedziczenia.
Wszystkiego trzeba używać z umiarem. Jak ktoś pakuje kompozycję wszędzie, gdzie się da, "bo można cośtam", to jest to takie samo nadużycie, jak próba rozwiązywania wszystkich problemów świata przez dziedziczenie albo wielokrotne dziedziczenie. Więc nie żadne książki itd. a zwykłe myślenie i ludzka inteligencja są najważniejsze, bo to programista pisze kod i programista wie (a przynajmniej powinien), w jakim kierunku powinien on podążać i co powinno być dozwolone. Co komu z tego, że przeczyta książkę o wzorcach projektowych i później najchętniej to by rozszerzanie modelu o własną funkcjonalność w Doctrine w oparciu o kompozycję robił "bo a nuż mu przyjdzie jakiś hardcore'owy pomysł na rozszerzanie tego w trakcie działania". Nieukiem to można być, rzucając się bez głębszego zastanowienia na każdą nowinkę, jaką się gdzieś przeczytało, a nie dlatego, że tu się użyło dziedziczenia, a tam nie. Mój przykład jako rozbudowa przykładu ndx:
1. Piszę szachy. Zasady tej gry powstały 1000 lat temu. Jaka jest szansa, że będę dodawać nowe ruchy itd? Zerowa. Więc dziedziczenie, bo jest prostsze i rozwiązywane w czasie kompilacji, zatem nie ma co się męczyć i spowalniać programu, bo jakaś książka mówi cośtam (mówi to przy założeniu, że autor myśli, co robi).
2. Piszę aplikację do grania w różne odmiany szachów. Każda odmiana ma różne specyficzne reguły, a ponadto np. w "szachach chłopskich" sposób poruszania się figury na planszy może ulegać zmianie w trakcie gry (a użytkownik może chcieć robić własne odmiany). Paradoksalnie, ilość możliwych kombinacji jest wystarczającym argumentem na to, aby tych ruchów nie kodować na sztywno w postaci mnóstwa klas - można je dość prosto opisać jakimś abstrakcyjnym językiem, napisać parser i zrobić jedną klasę, która potrafi się poruszać na podstawie zadanych reguł. Dopiero aby ruchy mogły zmieniać się w trakcie gry, użyłbym kompozycji, i to zorientowanej bardziej na zmianę danych opisujących ruch, a nie jednego obiektu na inny.
Dziedziczenie, wielokrotne dziedziczenie, kompozycja, to tylko narzędzia, a nie cel sam w sobie. Niektóre bardziej niebezpieczne i stwarzające problemy w samym języku (wielokrotne dziedziczenie), inne mniej, ale niewłaściwe użycie to niewłaściwe użycie. Czasem istnieje więcej, niż jedno dobre rozwiązanie i liczą się potrzeby. Dwie możliwe wypowiedzi dotyczące tego samego hipotetycznego kawałka kodu:
1. Użyłem tego rozwiązania, ponieważ daje ono możliwość XXX, z której w istotny sposób korzysta część aplikacji Y. Ponadto użytkownik musi mieć możliwość PPP do wykonania czynności Z, niezbędnej w niektórych sytuacjach.
2. Użyłem tego rozwiązania, ponieważ daje ono możliwość XXX. Jest ona bardzo przydatna, w przeciwieństwie do rozwiązania Y, które wielu często nadużywa, a które jej nie posiada, a wiele zalet tej możliwości można znaleźć np. w książce PPP.
Pozostawiam wam to do przemyślenia i dodam jedynie, że wolałbym pracować z programistą #1...
plurr
13.05.2009, 11:08:23
Faktycznie przyklad szachow jest niezbyt trafiony, jako ze zasady sa znane od wiekow i nie potrzeba tam wprowadzac jakichs kosmicznych rozwiazan. Co za tym idzie, klasa bazowa raczej sie nie zmieni, nie bedzie poprawek w klasie dziedziczacej. Jednakze rozwiazania w tworzonych systemach czesto odbiegaja od takich znanych przykladow - jesli piszemy cos nowego pod konkretna firme to trudno wszystko przewidziec i lepiej dmuchac na zimne, zadawac sobie pytanie "a co jesli klient sobie zazyczy?"
Zastanawiajac sie nad tym gdize stosowac dziedziczenie, a raczej gdzie go nie stosowac (na rzecz innych rozwiazan), mozna uniknac w przyszlosci zmian w wiecej niz 1 klasie. Pomimo tego ze system jest pisany obiektowo z wykorzystaniem mvc, moze powstac z niego spagetti. Wg mnie lepiej starac sie pisac klasy, ktore sa ze soba powiazane w jak najmniejszym stopniu.
Jedno jest pewne, nikt nie chcialby pracowac z programista, ktory dziedziczy po czym sie da - "bo to jest fajne, bo mam latwy dostep do obiektow klasy bazowej", bez zastanowienia.
marcio
13.05.2009, 13:12:31
Zgadzam sie z wami @plurr i @Zyx dziedziczenie powinno sie stosowac tylko wtedy gdy jest to napewno potrzebne.
Cytat
Jedno jest pewne, nikt nie chcialby pracowac z programista, ktory dziedziczy po czym sie da - "bo to jest fajne, bo mam latwy dostep do obiektow klasy bazowej", bez zastanowienia.
Wedlug mnie lepiej jest przekzywac obiekty np do kontruktora danej klasy bez podawania jakiej klasy ma byc i jest to latwiejsze.
Cytat
w c# i javie można powiedzieć całkowicie zrezygnowano ze wskaźników
W javie owszem jednak w C# jest taka mozliwosc jak nie wiesz o tym poczytaj o Unsafe w .Net dla C#
Crozin
13.05.2009, 13:26:20
Cytat
Jedno jest pewne, nikt nie chcialby pracowac z programista, ktory dziedziczy po czym sie da - "bo to jest fajne, bo mam latwy dostep do obiektow klasy bazowej", bez zastanowienia.
Ale to my tu omawiamy normalne czy patologiczne sytuacje? Bo oczywste jest, że nikt nie chce pracować z kimś kto nie ma pojęcia co robi.
Dziedziczenie jest dobre i bardzo pomocne jeżeli się z niego korzysta właściwie. Podobnie jak obiekty/tablice/stałe/funkcje/metody statyczne/interfacey/czy cokolwiek innego
jeżeli się z tego korzysta tak, jak się powinno.
I proszę bez przykładów:
dziedziczenie jest be, bo ktoś zrobił
<?php
class EkspresDoKawy extends Biuro
?>
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.