Jeśli mam kilka klas z funkcjami, których potrzebuję, ale chcę przechowywać je oddzielnie dla organizacji, czy mogę rozszerzyć klasę, aby mieć obie?
to znaczy class a extends b extends c
edycja: Wiem, jak rozszerzać klasy pojedynczo, ale szukam metody, aby natychmiast rozszerzyć klasę za pomocą wielu klas bazowych - AFAIK, nie możesz tego zrobić w PHP, ale powinny być sposoby obejścia tego bez uciekania się do class c extends b
,class b extends a
Odpowiedzi:
Odpowiadając na zmianę:
Jeśli naprawdę chcesz sfałszować wielokrotne dziedziczenie, możesz użyć magicznej funkcji __call ().
To jest brzydkie, chociaż działa z punktu widzenia użytkownika klasy A:
Wyświetla „abcdef”
źródło
Nie możesz mieć klasy, która rozszerza dwie klasy bazowe. Nie mogłeś.
Możesz jednak mieć następującą hierarchię ...
i tak dalej.
źródło
Możesz użyć cech, które, miejmy nadzieję, będą dostępne w PHP 5.4.
Cechy to mechanizm ponownego wykorzystania kodu w pojedynczych językach dziedziczenia, takich jak PHP. Cecha ma na celu zmniejszenie niektórych ograniczeń pojedynczego dziedziczenia poprzez umożliwienie programiście swobodnego ponownego wykorzystywania zestawów metod w kilku niezależnych klasach żyjących w różnych hierarchiach klas. Semantyka kombinacji cech i klas jest zdefiniowana w sposób, który zmniejsza złożoność i pozwala uniknąć typowych problemów związanych z dziedziczeniem wielokrotnym i mieszankami.
Są znane ze swojego potencjału w zakresie wspierania lepszej kompozycji i ponownego wykorzystania, stąd ich integracja z nowszymi wersjami języków, takich jak Perl 6, Squeak, Scala, Slate i Fortress. Cechy zostały również przeniesione na Javę i C #.
Więcej informacji: https://wiki.php.net/rfc/traits
źródło
Zajęcia nie mają być tylko zbiorem metod. Klasa ma reprezentować abstrakcyjną koncepcję, zawierającą zarówno stan (pola), jak i zachowanie (metody), które zmienia stan. Używanie dziedziczenia tylko po to, by uzyskać pożądane zachowanie, brzmi jak zły projekt obiektu obiektowego i jest dokładnie powodem, dla którego wiele języków nie zezwala na wielokrotne dziedziczenie: aby zapobiec „dziedziczeniu spaghetti”, tj. Rozszerzając 3 klasy, ponieważ każda ma metodę, której potrzebujesz, i kończy się na klasa, która dziedziczy 100 metod i 20 pól, ale zawsze używa tylko 5 z nich.
źródło
Sądzę, że są plany dodania wkrótce miksów.
Ale do tego czasu stosuj zaakceptowaną odpowiedź. Możesz to nieco wyodrębnić, aby utworzyć klasę „rozszerzalną”:
Zauważ, że w tym modelu „OtherClass” „wie” o $ foo. OtherClass musi mieć funkcję publiczną o nazwie „setExtendee”, aby ustawić tę relację. Następnie, jeśli jego metody są wywoływane z $ foo, może uzyskać dostęp do $ foo wewnętrznie. Nie uzyska jednak dostępu do żadnych prywatnych / chronionych metod / zmiennych, takich jak prawdziwa klasa rozszerzona.
źródło
Użyj cech jako klas podstawowych. Następnie użyj ich w klasie nadrzędnej. Przedłuż to.
Spójrzmy teraz na kobietę biznesu, która logicznie odziedziczyła biznes i ludzi;
źródło
BusinessWoman
zamiastBusinessPerson
? Wtedy możesz mieć rzeczywiste wielokrotne dziedziczenie.źródło
Aktualnie akceptowana odpowiedź @Franck będzie działać, ale w rzeczywistości nie jest to dziedziczenie wielokrotne, ale instancja potomna klasy zdefiniowanej poza zakresem, jest też
__call()
skrót - rozważ użycie$this->childInstance->method(args)
wszędzie tam, gdzie potrzebujesz metody klasy ExternalClass w klasie „rozszerzonej”.Dokładna odpowiedź
Nie, nie możesz, odpowiednio, nie, ponieważ instrukcja
extends
słowa kluczowego mówi:Prawdziwa odpowiedź
Jednak, jak poprawnie zasugerował @adam, NIE zabrania to używania wielokrotnego dziedziczenia hierarchicznego.
MOŻESZ rozszerzyć jedną klasę o inną, o kolejną i tak dalej ...
Takim prostym przykładem byłoby:
Ważna uwaga
Jak pewnie zauważyłeś, możesz wykonywać wielokrotne (2+) intehritance przez hierarchię tylko wtedy, gdy masz kontrolę nad wszystkimi klasami wchodzącymi w skład procesu - oznacza to, że nie możesz zastosować tego rozwiązania np. Z klasami wbudowanymi lub z klasami, które po prostu nie można edytować - jeśli chcesz to zrobić, pozostaje rozwiązanie @Franck - instancje podrzędne.
... I na koniec przykład z wynikami:
Które wyjścia
źródło
Przeczytałem kilka artykułów odradzających dziedziczenie w projektach (w przeciwieństwie do bibliotek / frameworków) i zachęcających do programowania interfejsów agaisnt, nie przeciwko implementacjom.
Popierają również OO ze względu na skład: jeśli potrzebujesz funkcji w klasie a i b, spraw, aby c miał elementy / pola tego typu:
źródło
Dziedziczenie wielokrotne wydaje się działać na poziomie interfejsu. Zrobiłem test na php 5.6.1.
Oto działający kod:
Nie sądziłem, że to możliwe, ale natknąłem się na kod źródłowy SwiftMailer, w klasie Swift_Transport_IoBuffer, która ma następującą definicję:
Jeszcze się tym nie bawiłem, ale pomyślałem, że podzielenie się nim może być interesujące.
źródło
Właśnie rozwiązałem mój problem z dziedziczeniem wielokrotnym:
W ten sposób mam możliwość manipulowania sesją wewnątrz SessionResponse, która rozszerza MyServiceResponsetype o możliwość samodzielnej obsługi sesji.
źródło
Jeśli chcesz sprawdzić, czy funkcja jest publiczna, zajrzyj do tego tematu: https://stackoverflow.com/a/4160928/2226755
I użyj metody call_user_func_array (...) dla wielu argumentów lub nie.
Lubię to :
źródło
Możesz to zrobić używając funkcji w PHP, które zostały ogłoszone w PHP 5.4
Oto krótki samouczek dla Ciebie, http://culttt.com/2014/06/25/php-traits/
źródło
PHP nie obsługuje jeszcze dziedziczenia wielu klas, obsługuje jednak dziedziczenie wielu interfejsów.
Zobacz http://www.hudzilla.org/php/6_17_0.php po kilka przykładów.
źródło
PHP nie pozwala na wielokrotne dziedziczenie, ale możesz to zrobić, implementując wiele interfejsów. Jeśli implementacja jest „ciężka”, podaj szkieletową implementację dla każdego interfejsu w osobnej klasie. Następnie możesz delegować wszystkie klasy interfejsu do tych szkieletowych implementacji poprzez zawieranie obiektów .
źródło
Nie wiedząc dokładnie, co próbujesz osiągnąć, sugerowałbym przyjrzenie się możliwości przeprojektowania aplikacji tak, aby w tym przypadku używała kompozycji zamiast dziedziczenia.
źródło
Zawsze dobrym pomysłem jest stworzenie klasy nadrzędnej z funkcjami ... tj. Dodanie tej całej funkcjonalności do klasy rodzica.
I „przenieś” wszystkie klasy, które używają tego hierarchicznie w dół. Potrzebuję - przepisanie funkcji, które są specyficzne.
źródło
Jednym z problemów PHP jako języka programowania jest fakt, że możesz mieć tylko jedno dziedzictwo. Oznacza to, że klasa może dziedziczyć tylko z jednej innej klasy.
Jednak często warto dziedziczyć z wielu klas. Na przykład może być pożądane, aby dziedziczyć metody z kilku różnych klas, aby zapobiec duplikowaniu kodu.
Ten problem może prowadzić do tego, że klasa ma długą rodzinną historię dziedziczenia, co często nie ma sensu.
W PHP 5.4 dodano nową funkcję języka znaną jako Cechy. Cecha jest czymś w rodzaju Mixina, ponieważ pozwala na mieszanie klas cech z istniejącą klasą. Oznacza to, że możesz zredukować powielanie kodu i uzyskać korzyści, unikając jednocześnie problemów związanych z wielokrotnym dziedziczeniem.
Cechy
źródło
To nie jest prawdziwa odpowiedź, mamy zduplikowaną klasę
... ale działa :)
klasa copy_B to kopia całej klasy B.
teraz
źródło
klasa A rozszerza B {}
klasa B rozszerza C {}
Następnie A przedłużył zarówno B, jak i C.
źródło
B
. W większości przypadków chcemy mieć dwie niepowiązane ze sobą klasyB
iC
(prawdopodobnie z różnych bibliotek) i być jednocześnie dziedziczonymi przezA
takie, któreA
zawierają wszystko z obuB
iC
, aleB
nie zawierają niczego zC
i na odwrót.