Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> klasy abstrakcyjne
Jarod
post
Post #1





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

Ostrzeżenie: (0%)
-----


Tworząc interfejs używamy słowa abstract przy definicji metod.

Po co używa się tego słowa przy definicji klas (lub funkcji - w przypadku gdy nie jest to interfejs) ?
W jakim celu tworzyć abstrackyjne klasy?


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
2 Stron V   1 2 >  
Start new topic
Odpowiedzi (1 - 19)
Apo
post
Post #2





Grupa: Zarejestrowani
Postów: 426
Pomógł: 1
Dołączył: 2.10.2005

Ostrzeżenie: (0%)
-----


W przeciwieństwie do interfejsów w klasach abstrakcyjnych masz ciało metod, czyli częściowe zaimplementowanie interfejsu, możesz wymuszać obecność metod w klasach jak i iniemożliwić nadpisanie innej itp.

Fajnym przykładem może być obsługa akcji w frameworkach np:

  1. <?php
  2. abstract class SzablonAkcji {
  3.  
  4. protected $przywileje = array('public');
  5.  
  6. abstract public function akcjaAlternatywna(); // wymuszamy utworzenie tej metody w klasach dziedziczących
  7.  
  8. final function OdpalAkcje() // w klasach dziedziczących nie mozemy nadpisac tej metody
  9. {
  10. $action = new HttpRequest->get('action');
  11. $action = $this->$action . '()';
  12.  
  13. if(method_exists($action, $this))
  14. $this->action;
  15. else
  16. $this->akcjaAlternatywna();
  17. }
  18. }?>


Stworzony został prosty szkielet do obsługi akcji, czyli wywoływania odpowiednich metod na podstawie urla, aby wyświetlić przykładowo newsy musimy utworzyć klasa WyswietlNewsy która będzie dziedziczyć nasz SzablonAkcji.

  1. <?php
  2.  
  3. class WyswietlNewsy extends SzablonAkcji {
  4.  
  5. protected $przywileje('admin');
  6.  
  7. public function AkcjaAlternatywna()
  8. {
  9. echo 'Błąd obsługi akcji';
  10. }
  11.  
  12. public function WyswietlNewsy()
  13. {
  14. // wyswietlanie newsow
  15. }
  16.  
  17. }
  18. ?>


Pisałem z palca więc mogą byc błędy, ale myślę że teraz wiesz miej więcej jak to działa smile.gif
Go to the top of the page
+Quote Post
envp
post
Post #3





Grupa: Zarejestrowani
Postów: 359
Pomógł: 1
Dołączył: 16.04.2006
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Heh wytlumaczone dobrze, ale dziwnie. smile.gif J4r0d: pojęcie interfejsu znasz prawda? więc wyobraź sobie teraz ze masz 10 klas, ktore dziedzicza ten inerfejs (niech to bedzie metoda foo()) i dla tych klas metoda foo() wyglda tak samo, gdybys uzywal tylko interfesjow musail bys napisac 10 razy ten sam kod, a tak tworzysz sobie klase abstrakcyjna i ona zawiera juz cale cialo metody foo(). Dodatkowo powiem, ze nie mozesz utworzyc instacji ani odwolac sie do pola klasy abstrakcyjnej - czyli sama w sobie jest bezuzyteczna, uzywamy jej jedynnie jako rodzica innej klasy. Btw. Ten temat byl juz poruszany....

Ten post edytował envp 10.08.2006, 03:12:32
Go to the top of the page
+Quote Post
Ludvik
post
Post #4





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Klasy abstrakcyjne nie są wygodnym narzędziem do definiowania interfejsów. Sprawdzają się, kiedy musisz wymusić na potomkach określony zestaw metod, w którym część kodu metod jest wspólna. Ponadto przydają się przy takich wzorcach jak Template Method.

Cytat
Dodatkowo powiem, ze nie mozesz utworzyc instacji ani odwolac sie do pola klasy abstrakcyjnej - czyli sama w sobie jest bezuzyteczna, uzywamy jej jedynnie jako rodzica innej klasy.

To nie jest do końca prawdą. Statyczne metody i właściwości klasy abstrakcyjnej nie zmieniają swojego zachowania. Dobrym nawykiem jest zadeklarowanie klasy jako abstrakcyjnej w przypadku, gdy cały jej interfejs tworzą metody statyczne i nie ma ona sensu w kontekście instancji. Dla przykładu przywołać można szczególną postać wzorca Registry.

  1. <?php
  2. abstract class Registry {
  3. public static function get($mKey) {
  4. //...
  5. }
  6.  
  7. public static function set($mKey) {
  8.  //...
  9.  }
  10.  
  11. public static function unset($mKey) {
  12.  //...
  13.  }
  14.  
  15. public static function has($mKey) {
  16.  //...
  17.  }
  18.  
  19. private static $registry = array();
  20. }
  21. ?>


Ten post edytował Ludvik 10.08.2006, 10:02:00


--------------------
Go to the top of the page
+Quote Post
Jarod
post
Post #5





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

Ostrzeżenie: (0%)
-----


Mniej więcej łapie. Wychodzi na to, że lepiej używać klas abstrakcyjnych niż interfejsów. Dziwni mnie tylko, że w książce PHP5 zaaw. progr. nie ma (przynajmniej we wprowadzeniu do OOP) wzmianki o czymś takim jak final czy klasy anstrakcyjne.. :/


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
Ludvik
post
Post #6





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Cytat
Wychodzi na to, że lepiej używać klas abstrakcyjnych niż interfejsów.

A skąd ten wniosek? To są narzędzia do dwóch podobnych, ale jednak różnych celów. Jeżeli chcesz zdefiniować tylko wymagany interfejs klasy, to używasz interfejsów. Jeżeli potrzebujesz utworzyć szkielet klasy, wtedy definiujesz klasę abstrakcyjną. Pamiętaj o jednej, znaczącej przewadze interfejsów. Możesz implementować wiele interfejsów w jednej klasie. Wielodziedziczenie w php nie istnieje.

W moich projektach na 10 (jeżeli nie więcej) interfejsów przypada mniej więcej jedna klasa abstrakcyjna.


--------------------
Go to the top of the page
+Quote Post
Jarod
post
Post #7





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

Ostrzeżenie: (0%)
-----


Cytat(Ludvik @ 10.08.2006, 18:29 ) *
Pamiętaj o jednej, znaczącej przewadze interfejsów. Możesz implementować wiele interfejsów w jednej klasie.


Przecież zapis nie ma prawa bytu
  1. <?php
  2. class NazwaKlas implements Interfejs1, Interfejs2
  3. {
  4.  
  5. }
  6. ?>


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
Ludvik
post
Post #8





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


A sprawdziłeś czy to działa? Na mój gust działa... Tak się składa, że takie konstrukcje często się spotyka i od dawna jest mowa o tym, że w PHP5 można symulować wielodziedziczenie właśnie w taki sposób.

Mimo wszystko, najlepiej sprawdzić kod przed wysłaniem posta smile.gif


--------------------
Go to the top of the page
+Quote Post
Jarod
post
Post #9





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

Ostrzeżenie: (0%)
-----


Cytat(Ludvik @ 10.08.2006, 21:46 ) *
A sprawdziłeś czy to działa? Na mój gust działa... Tak się składa, że takie konstrukcje często się spotyka i od dawna jest mowa o tym, że w PHP5 można symulować wielodziedziczenie właśnie w taki sposób.

Mimo wszystko, najlepiej sprawdzić kod przed wysłaniem posta smile.gif



lol strzelałem, wyssałem z palca tongue.gif

Po co klasa ma implementować dwa interfejsy? Nie potrafię sobie tego wyobrazić. Tzn. wyobrazić mogę tylko nie łapie sensu ..


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
Ludvik
post
Post #10





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Kilka tematów niżej jest przykładowa odpowiedź.


--------------------
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #11





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Sporo sensu to ma.
np. interfejsy:
1. save(), load()
2. setCommand(), executeCommand()

Juz masz 2 inetrfejsy - uważasz, że można te cztery metody umieścic w jednym intefejsie? Jak go nazwiesz?


--------------------
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.
Go to the top of the page
+Quote Post
Jarod
post
Post #12





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

Ostrzeżenie: (0%)
-----


Cytat(envp @ 10.08.2006, 02:10 ) *
Heh wytlumaczone dobrze, ale dziwnie. smile.gif J4r0d: pojęcie interfejsu znasz prawda? więc wyobraź sobie teraz ze masz 10 klas, ktore dziedzicza ten inerfejs (niech to bedzie metoda foo()) i dla tych klas metoda foo() wyglda tak samo, gdybys uzywal tylko interfesjow musail bys napisac 10 razy ten sam kod,


Zgadza się. Dotąd rozumiem.

Cytat(envp @ 10.08.2006, 02:10 ) *
a tak tworzysz sobie klase abstrakcyjna i ona zawiera juz cale cialo metody foo().


No dobra, czyli masz interfejs:
  1. <?php
  2. interface Metody {
  3. abstract function metoda1();
  4. abstract function metoda2();
  5. }
  6. ?>

i klasę abstrakcyjną:
  1. <?php
  2. abstract class Abstrakcja {
  3. public function foo() {
  4. //... kod metody
  5. }
  6. }
  7. ?>



1. I jak teraz utworzysz klasę, która implementuje interfejs Metody i jednocześnie dziedziczą po klasie Abstrakcja ?

2. Co dokładnie daje dodanie słowa static po słowie function?


Cytat(Apo @ 9.08.2006, 18:56 ) *
(...)
Fajnym przykładem może być obsługa akcji w frameworkach np:
  1. <?php
  2. abstract class SzablonAkcji {
  3.  
  4. protected $przywileje = array('public');
  5.  
  6. abstract public function akcjaAlternatywna(); // wymuszamy utworzenie tej metody w klasach dziedziczących
  7.  
  8. final function OdpalAkcje() // w klasach dziedziczących nie mozemy nadpisac tej metody
  9. {
  10. $action = new HttpRequest->get('action');
  11. $action = $this->$action . '()';
  12.  
  13. if(method_exists($action, $this))
  14. $this->action;
  15. else
  16. $this->akcjaAlternatywna();
  17. }
  18. }?>


Coś jest nie tak w metodzie OdpalAkcje(). Nie powinno być:
  1. <?php
  2. $action = new HttpRequest();
  3. $action = action->get('action');
  4. $action = $this->$action . '()';
  5. ?>

? Nie czaje ale to może dlatego, że to jest kawałek kodu.


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
Ludvik
post
Post #13





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


W definicji interfejsów nie używamy słowa abstract. Interfejs zawsze definiuje tylko sposób wysłania komunikatu do obiektu.

Dziedzicząc można spokojnie implementować interfejsy.
  1. <?php
  2. class Konkretna extends Abstrakcyjna implements Interfejs1, Interfejs2, Interfejs3 {
  3. // Definicja klasy...
  4. }
  5. ?>


Poczytaj phpedię... Metody statyczne operują na danych statycznych, czyli zajmujących stałe miejsce w pamięci i wywoływanych z kontekstu klasy, a nie obiektu. Metody i właściwości statyczne są dostępne bez konieczności tworzenia obiektów klasy.


--------------------
Go to the top of the page
+Quote Post
Apo
post
Post #14





Grupa: Zarejestrowani
Postów: 426
Pomógł: 1
Dołączył: 2.10.2005

Ostrzeżenie: (0%)
-----


Cytat
2. Co dokładnie daje dodanie słowa static po słowie function?

Nie musisz tworzyć obiektu klasy aby wywołać metode, np singleton. Do metody statycznej odwołujesz się:
NazwaKlasy::metoda();

Cytat
Coś jest nie tak w metodzie OdpalAkcje(). Nie powinno być:
  1. <?php
  2. $action = new HttpRequest();
  3. $action = action->get('action');
  4. $action = $this->$action . '()';
  5. ?>

? Nie czaje ale to może dlatego, że to jest kawałek kodu.


No ja w tym fragmencie popełniłem błąd, teraz jest dobrze.
Go to the top of the page
+Quote Post
Jarod
post
Post #15





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

Ostrzeżenie: (0%)
-----


Cytat(Apo @ 12.08.2006, 08:39 ) *
Nie musisz tworzyć obiektu klasy aby wywołać metode, np singleton. Do metody statycznej odwołujesz się:
NazwaKlasy::metoda();


Łapie. Mam jeszcze jedno pytanie. Żeby móc odwoływać się do klasy bez tworzenia obiektu, klasa musi być static.

Ostatnio widziałem gdzieś klasę statyczną, której kilka metod było statycznych a reszta nie. I co wtedy? Bez tworzenia obiektów możemy odwoływać się tylko do metod statycznych? A do pozostałych?


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #16





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




A do pozostałych nie laugh.gif - o to właśnie chodzi.Własnie we wzorcu singleton jest pokazana współpraca metod statycznych z niestatycznymi. Do metody statycznej możesz sie odwołac z kontekstu całej aplikacji - wystarczy, ze zadeklarowałeś wcześniej klasę. Jeśli stworzysz obiekt, to już musisz zacząć się o niego martwić tzn. brac poprawki np. na umiejscownienie obiektu smile.gif

Pozdrawiam


--------------------
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.
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #17





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Nie ma klas statycznych, moga byc tylko metody statyczne ktore wywolujesz:
NazwaKlasy::nazwaMetody()


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Jarod
post
Post #18





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

Ostrzeżenie: (0%)
-----


Cytat(Cysiaczek @ 24.08.2006, 19:35 ) *
Jeśli stworzysz obiekt, to już musisz zacząć się o niego martwić tzn. brac poprawki np. na umiejscownienie obiektu smile.gif

Możesz to rozwinąć? Jakie umiejscowienie?


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #19





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Faktycznie - trochę nieściśle się wyraziłem. laugh.gif

Chodzi o zwykły zasięg zmiennych. Jak stworzysz obiekt, to jest on przypisanu do jakiejś zmiennej. Od tego momentu musisz przekazywać jej referencję (lub kopię) do klas, funkcji, etc, jeśli chesz skorzystać z obiektu.

Pozdrawiam.

Ten post edytował Cysiaczek 24.08.2006, 21:28:02


--------------------
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.
Go to the top of the page
+Quote Post
thornag
post
Post #20





Grupa: Zarejestrowani
Postów: 504
Pomógł: 2
Dołączył: 31.03.2006
Skąd: Londyn

Ostrzeżenie: (0%)
-----


@J4r0d Wracajac jeszcze do pytania abstrakcyjne. Pamietasz swoje pytanie dotyczace przekazywania parametrow do metod w stylu addItem(Item $item).

Jasnym jest ze mozesz przekazac tutaj wszystkie instancje class ktore implementuja interfejs Item. Powiedzmy ze ten interfejs wymusza implementacje metody Pokaz() i Schowaj().
A co jesli 4 klasy ktorych chcesz uzywac maja taka sama metode Schowaj() ?
Bedziesz ja przepisywac od nowa ? No nie a tak to mozesz utworzyc abstrakcyjna klase Item w ktorej bedzie ta wpolna metoda w pelni zaimplementowana no i wymuszisz implementacje Pokaz().

Mozna by powiedziec ze po co mi abstrakcja skoro mozna dziedziczyc po zwyklej. No tak ale zwykla klasa nie wymusisz implementacji metody Pokaz() pozatym nie ma sensu tworzyc instancji klasy zawierajacej sama metode Schowaj() wiec tutaj przydaje sie abstrakcja. Nie dosc ze masz zapewnione to ze wszystkie kalsy beda mialy zaimplementowane wymagane przez Ciebie metody to jeszcze korzystasz z zalet dziedziczenia. Swoja droga to sie chyba nazywa polimorfizm winksmiley.jpg to ze klasa wie od jakiej klasy pochodzi i mozna ja przekazac do metody jak wyzej.


--------------------
"Wizja czasu jest szeroka, lecz kiedy sie przez nia przechodzi, czas staje sie waskimi drzwiami"

Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 09:12