Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP/OOP]interfejsy,abstrakcja i metody statyczne
Forum PHP.pl > Forum > PHP > Object-oriented programming
marcio
Witam wiem ze jest to drugi watek z rzedu ale na poprzedni nikt nie udzieli mi odpowiedzi wiec chce zapytac jeszcze raz ale dokladniej:

Nie rozumiem 3 rzeczy w 100%:
-Metody statyczne
-Klasy i metody abstrakcyjne
-interfejsy

Hmm skoro OOP to OOP i powinno sie pracowac na obiektach to po co sa "statyczne" w ktorych nie tworzy sie obiektu a operuje jak na zwyklych zmiennych czy ktos moze mi wytlumaczyc jej zastosowania?

I teraz klasy abstrakcyjne i implementowanie interfejsow wiem ze klasy abstrakcyjne i interfejsy to klasy ktore rozszerzaja inne klasy(jesli klasa pochodna po niej dziedziczy) czytalem tez ze klasy abstrakcyjne uzywa sie do malych projektow a interfejsy do duzycy jednak nie rozumiem jednej rzeczy: http://webcity.pl/webcity/programowanie_ob...e_w_php_5_cz__3 a dokladnie pierwszy kod z uzyciem interfejsow i jego cytat:
Cytat
Moglibyśmy stworzyć tutaj abstrakcyjną klasę bazową, ale wtedy uniemożliwilibyśmy programistom dziedziczenie z innych klas

i tego nie potrafie zrozumiec, i jeszcze jaka jest roznica miedzy klasa abstrakcyjna i interfejsem skoro obydwie "metody" maja rozszerzac inne klasy?

P.S i jeszcze jedno skoro klasy abstrakcyjne i interfejsy maja rozszerzac mozliwosci innych klas to dlaczego odrazu w takiej klasie nie mozna dac implementacji funkcji ktora ma byc potem dziedziczona/implementowana, jaki to ma sens skoro kazda klasa dziedziczaca moze miec funkcje inaczej pracujace?
dr_bonzo
Jej, bylo z 5 razy, sa duze topiki na forum o abstr. i interfejsach.

Cytat
Moglibyśmy stworzyć tutaj abstrakcyjną klasę bazową, ale wtedy uniemożliwilibyśmy programistom dziedziczenie z innych klas

Klasa abstrakcyjna BEZ zaimplementowania zadnych metod to wlasciwie interfejs. Roznica polega na tym ze dziedziczyc mozez tylko po jednej klasie, a implementowac mozesz dowolna ilosc interfejsow. Dlatego w tym przypadku interfejs jest lepszym rozwiazanie,m, bo uzycie klasy abstr. nie przynosi korzysci a tylko zabiera nam mozlliwosc innego dziedziczenia.

Cytat
Hmm skoro OOP to OOP i powinno sie pracowac na obiektach to po co sa "statyczne" w ktorych nie tworzy sie obiektu a operuje jak na zwyklych zmiennych czy ktos moze mi wytlumaczyc jej zastosowania?
No czasami nie da sie tylko niestatycznymi metodami operowac, tudziez obiektami. Poczytaj o wzorcach projektowych i zobacz jak tam z oop korzystaja, musisz jedynie wczesniej poznac polimorfizm najlepiej w jakims statycznym jezyku (c++, Java, C#) - latwiej to zalapac.
marcio
Cytat
Klasa abstrakcyjna BEZ zaimplementowania zadnych metod to wlasciwie interfejs

Czyli w przypadku gdy jest tylko deklaracja funkcji jelsi dobrze rozumiem

Mozesz dac jakis przyklad co do tego:
Cytat
Roznica polega na tym ze dziedziczyc mozez tylko po jednej klasie, a implementowac mozesz dowolna ilosc interfejsow


Chodzi o to ze np w interfejsach mozna robic tak
  1. <?php
  2. class jakas_klasa implements pierwszy, drugi, trzeci
  3. ?>

A za pomoca klas abtr. tylko tak:
  1. <?php
  2. class jakas_klasa extend klasa_abtrs
  3. ?>

questionmark.gif

Wiem ze bylo duzo razy ale nie rozumiem tego zabardzo

Cytat
musisz jedynie wczesniej poznac polimorfizm najlepiej w jakims statycznym jezyku (c++, Java, C#) - latwiej to zalapac.

Wlasnie problem w tym ze ucze siie Cpp i zanim dojde do OOP chcialbym pojac juz OOP z php zeby mi bylo latwiej

P.S czytam taki temat i chyba mniej wiecej wiem jak uzyc metody statyczne np dla klasy do obslugi mysql zamiast dziedziczyc ja w kazdej klasie ktora potrzebuje obsluge mysql mozna sie odwolywac do funckji Nazwa_klasy::metoda()
dr_bonzo
Cytat
Cytat
Roznica polega na tym ze dziedziczyc mozez tylko po jednej klasie, a implementowac mozesz dowolna ilosc interfejsow



Chodzi o to ze np w interfejsach mozna robic tak
A za pomoca klas abtr. tylko tak:

Dokladnie

Cytat
P.S czytam taki temat i chyba mniej wiecej wiem jak uzyc metody statyczne np dla klasy do obslugi mysql zamiast dziedziczyc ja w kazdej klasie ktora potrzebuje obsluge mysql mozna sie odwolywac do funckji Nazwa_klasy::metoda()

Tez zle, nie statycznie, tylko tworzysz obiekt polaczenia a potem go przekazujesz do innych obiektow, ew. uzywasz Singletona (http://www.googlesyndicatedsearch.com/u/forumphppl?q=baza+singleton&sa=Szukaj&domains=forum.php.pl&sitesearch=forum.php.pl itp)
marcio
No ok a powiedz mi np co powinno sie dawac do klas abstr. albo interefejsow jakie funkcje, takie ktore sa powiazane z calym systemem?

Cytat
Tez zle, nie statycznie, tylko tworzysz obiekt polaczenia a potem go przekazujesz do innych obiektow, ew. uzywasz Singletona


Np chodzi ci o takie cos:
  1. <?php
  2. class mysql {
  3.  
  4. // tutaj funkcje etc
  5.  
  6. }
  7.  
  8. class jakas_klasa {
  9.  
  10. // jakies funkcje a gdy jest potrzebne polaczenie to
  11.  
  12. $sql = new mysql;
  13.  
  14. //i potem n:
  15.  
  16. $zapytanie = $sql -> zapytanie('select * from costam.....');
  17.  
  18. }
  19. ?>


A np powiedz mi kiedy ty uzywasz metody statyczne?
Cysiaczek
Nie z całym systemem, tylko są wspólne dla pewnej grupy obiektów. Takie, które wiesz, że ich kod nie będzie zależny od konkretnego poddtypu obiektu.
Inaczej mówiąc: Jeśli jesteś pewien, że tworząc jakąś rodzinę obiektów pewne operacje będą wspólne, ale niektóre metody muszą te podklasy implementować we właściwy im sposób i muszą to robić zawsze, to opłaca się zrobić klasę abstrakcyjną.

--edit
Metod statycznych używasz tam, gdzie wykonujesz operacje nie związane bezpośrednio z danym obiektem (to jest ważne - obiekt posiada tożsamość), ale związane tematycznie z daną klasą lub rodziną klas.

Pozdrawiam.
marcio
Hmmm czytam rozne tematy z tego forum czy taki przyklad na bazie innych ale wymyslony przez ze mnie jest wlasciwy:?
  1. <?php
  2. interface pies {
  3.  
  4. function hal($pies, $halas);
  5. }
  6.  
  7. interface kot {
  8.  
  9. function mial($kot, $halas);
  10. }
  11.  
  12. interface czlowiek {
  13.  
  14. function mowa();
  15. }
  16.  
  17. abstract class wlasciwosci {
  18.  
  19. abstract function waga($waga);
  20. abstract function wysokosc($wysokosc);
  21. abstract function iq($kto);
  22.  
  23. }
  24.  
  25. class stworzenie extends wlasciwosci implements pies, kot {
  26.  
  27. private $zwierze;
  28.  
  29. public function __construct($zwierze) {
  30.  
  31. $this -> zwierze = $zwierze;
  32.  
  33.  }
  34.  
  35.  
  36. function hal($pies, $halas) {
  37.  
  38. if(is_string($pies) && $pies == 'pies') return $halas;
  39.  
  40. else return 'Ta funkcja nie obsluguje halasu takiego zwoerzecia';
  41.  
  42. }
  43.  
  44.  
  45. function mial($kot, $halas) {
  46.  
  47. if(is_string($kot) && $kot == 'kot') return $halas;
  48.  
  49. else return 'Ta funkcja nie obsluguje halasu takiego zwoerzecia';
  50.  
  51. }
  52.  
  53. public function waga($waga) {
  54.  
  55. return $waga;
  56.  
  57.  }
  58.  
  59. public function wysokosc($wysokosc) {
  60.  
  61. return $wysokosc;
  62.  
  63.  }
  64.  
  65. public function iq($kto) {
  66.  
  67. if($kto == 'kot') $ile = rand(1,10);
  68. else if($kto == 'pies') $ile = rand(10,50);
  69.  
  70. return $ile;
  71.  }
  72.  
  73. public function zwroc_zwierze() {
  74.  
  75. if(is_string($this -> zwierze)) return $this -> zwierze;
  76.  
  77. else return 'Argument musi byc typu int';
  78.  
  79.  }
  80. }
  81.  
  82. $zwierze = new stworzenie('pies');
  83. echo($zwierze -> zwroc_zwierze().' wazy '.$zwierze -> waga(4).'kg ma '.$zwierze -> wysokosc(30).'cm a jego iq to '.$zwierze -> iq($zwierze -> zwroc_zwierze()));
  84. if($zwierze -> zwroc_zwierze() == 'pies') echo('<Br>'.$zwierze -> hal('pies', 'hal hal').'<Br>');
  85. else echo('<Br>'.$zwierze -> mial('kot', 'mial mial').'<Br>');
  86.  
  87. // i potem implementacja klasy czlowiek
  88. ?>

A moze cos bardziej w ten desen:
  1. <?php
  2. interface pies {
  3.  
  4. function hal($pies, $halas);
  5. }
  6.  
  7. interface kot {
  8.  
  9. function mial($kot, $halas);
  10. }
  11.  
  12. interface czlowiek {
  13.  
  14. function mowa($zdanie);
  15. }
  16.  
  17. abstract class wlasciwosci {
  18.  
  19. abstract function waga($waga);
  20. abstract function wysokosc($wysokosc);
  21. abstract function iq($kto);
  22.  
  23. }
  24.  
  25. class stworzenie extends wlasciwosci {
  26.  
  27. private $zwierze;
  28.  
  29. public function __construct($zwierze) {
  30.  
  31. $this -> zwierze = $zwierze;
  32.  
  33.  }
  34.  
  35. public function waga($waga) {
  36.  
  37. return $waga;
  38.  
  39.  }
  40.  
  41. public function wysokosc($wysokosc) {
  42.  
  43. return $wysokosc;
  44.  
  45.  }
  46.  
  47. public function iq($kto) {
  48.  
  49. if($kto == 'kot') $ile = rand(1,10);
  50. else if($kto == 'pies') $ile = rand(10,50);
  51. else if($kto == 'czlowiek') $ile = rand(50, 100);
  52.  
  53. return $ile;
  54.  }
  55.  
  56. public function zwroc_zwierze() {
  57.  
  58. if(is_string($this -> zwierze)) return $this -> zwierze;
  59.  
  60. else return 'Argument musi byc typu string';
  61.  
  62.  }
  63. }
  64.  
  65. class zwierzeta extends stworzenie implements pies, kot {
  66.  
  67. function hal($pies, $halas) {
  68.  
  69. if(is_string($pies) && $pies == 'pies') return $halas;
  70.  
  71. else return 'Ta funkcja nie obsluguje halasu takiego zwoerzecia';
  72.  
  73. }
  74.  
  75.  
  76. function mial($kot, $halas) {
  77.  
  78. if(is_string($kot) && $kot == 'kot') return $halas;
  79.  
  80. else return 'Ta funkcja nie obsluguje halasu takiego zwoerzecia';
  81.  
  82.  }
  83. }
  84.  
  85. class ludzie extends stworzenie implements czlowiek {
  86.  
  87. function mowa($zdanie) {
  88.  
  89. if(is_string($zdanie)) return $zdanie;
  90.  }
  91. }
  92.  
  93. $zwierze = new zwierzeta('kot');
  94. echo($zwierze -> zwroc_zwierze().' wazy '.$zwierze -> waga(4).'kg ma '.$zwierze -> wysokosc(30).'cm a jego iq to '.$zwierze -> iq($zwierze -> zwroc_zwierze()).'<Br>');
  95. if($zwierze -> zwroc_zwierze() == 'pies') echo $zwierze -> hal($zwierze -> zwroc_zwierze(), 'hal hal');
  96. else echo $zwierze -> mial($zwierze -> zwroc_zwierze(), 'mial mial');
  97.  
  98. echo('<Br>');
  99.  
  100. $czlowiek = new ludzie('czlowiek');
  101. echo($czlowiek -> zwroc_zwierze().' wazy '.$czlowiek -> waga(4).'kg ma '.$czlowiek -> wysokosc(30).'cm a jego iq to '.$czlowiek -> iq($czlowiek -> zwroc_zwierze()).'<Br>');
  102. echo $czlowiek -> mowa('Yoyo ziomale');
  103. ?>

A jesli zle to jakby napisac takie cos jak zrozumialem spruboje napisac jakas klase

P.S i po co jest takie cos:
  1. <?php
  2. function addItem(Item $item) {
  3.        foreach($this->items as $thisItem){
  4.            if($item === $thisItem){
  5.                return;
  6.            }
  7. ?>

Na czym polega tworzenie obiektu w funkcji?

Cytat
Metod statycznych używasz tam, gdzie wykonujesz operacje nie związane bezpośrednio z danym obiektem (to jest ważne - obiekt posiada tożsamość), ale związane tematycznie z daną klasą lub rodziną klas.

Dalej nie rozumiem masz jakis przyklad?
dr_bonzo
1. Interfejsy, przyklad rzeczywisty z mojego FW

  1. <?php
  2. class Framework_Session_SessionManager
  3. {
  4.    /**
  5.      * @var Framework_Session_SessionStorage $sessionStorage
  6.      */
  7.    private $sessionStorage;
  8.    public function __construct( Framework_Session_SessionStorage $sessionStorage )
  9.    {
  10.        $this->sessionStorage = $sessionStorage;
  11.    }
  12.    
  13.    /**
  14.      * @param string $sid session id
  15.      * @return Framework_Session_Session
  16.      */
  17.    public function initializeSession( $sid = null )
  18.    {
  19.        if ( is_null( $sid) )
  20.        {
  21.            $sid = $this->generateNewSID();
  22.        }
  23.        
  24.        if ( strlen( strval( $sid )) == 0 )
  25.        {
  26.            $sid = $this->generateNewSID();
  27.        }
  28.        
  29.        return $this->sessionStorage->loadSession( $sid );
  30.    }
  31.    
  32.    /**
  33.      * @param Framework_Session_Session $session
  34.      * @return boolean whether was successfull
  35.      */
  36.    public function finalizeSession( Framework_Session_Session $session  )
  37.    {
  38.        return $this->sessionStorage->storeSession($session);
  39.    }
  40.    
  41.    /**
  42.      * @return string new SID
  43.      */
  44.    private function generateNewSID()
  45.    {
  46.        return md5(uniqid());
  47.    }
  48. }
  49. ?>


Framework_Session_SessionStorage zajmuje sie zapisem i odczytem obiektu sesji, jako ze nie potrzebuje zaimplementowac tutaj
zadnej metody to wystarcza mi intefrejs
  1. <?php
  2. interface Framework_Session_SessionStorage
  3. {
  4.    /**
  5.      * Stores session object
  6.      * @param $session
  7.      * @return boolean
  8.      */
  9.    public function storeSession( Framework_Session_Session $session );
  10.    
  11.    /**
  12.      * Loads session object
  13.      * @param string $id ID of the session
  14.      * @return Framework_Session_Session
  15.      */
  16.    public function loadSession( $id );
  17.    
  18.    /**
  19.      * Removed session identified by $id
  20.      */
  21.    public function removeSession( $id );
  22.    
  23. }
  24. ?>



pierwsza implementacja interfejsu
  1. <?php
  2. class Framework_Session_FileSessionStorage implements Framework_Session_SessionStorage
  3. {
  4.    private $sessionsDir;
  5.    
  6.    public function __construct( $sessionsDir )
  7.    {
  8.        $this->sessionsDir = $sessionsDir;
  9.    }
  10.    
  11.    public function storeSession( Framework_Session_Session $session )
  12.    {
  13.        $id = $session->getID();
  14.        
  15.        $filename = $this->buildFilename( $id );
  16.        $serializedData = serialize( $session->getAllData() );
  17.        file_put_contents( $filename, $serializedData );
  18.        
  19.        return true;
  20.    }
  21.    
  22.    /**
  23.      * @param integer $id Session id
  24.      * @return Framework_Session_Session
  25.      */
  26.    public function loadSession( $id )
  27.    {
  28.        $filename = $this->buildFilename( $id );
  29.        
  30.        if ( ! file_exists( $filename ))
  31.        {
  32.            return new Framework_Session_Session( $id );
  33.        }
  34.        
  35.        $serializedData = file_get_contents( $filename );
  36.        if ( $serializedData === FALSE )
  37.        {
  38.            return new Framework_Session_Session( $id );
  39.        }
  40.        
  41.        $data = unserialize( $serializedData );
  42.        if ( $data === FALSE )
  43.        {
  44.            return new Framework_Session_Session( $id );
  45.        }
  46.        
  47.        $session = Framework_Session_SessionnewInstance( $id, $data );
  48.        return $session;
  49.    }
  50.    
  51.    public function removeSession( $id )
  52.    {
  53.        $filename = $this->buildFilename( $id );
  54.        if ( ! file_exists( $filename ))
  55.        {
  56.            return true;
  57.        }
  58.        
  59.        return unlink( $filename );
  60.    }
  61.    
  62.    private function buildFilename( $id )
  63.    {
  64.        $filename = $this->sessionsDir . "/sess_" . $id;
  65.        return $filename;
  66.    }
  67. }
  68. ?>


druga implementacja interfejsu
  1. <?php
  2. class Framework_Session_PDOSessionStorage implements Framework_Session_SessionStorage
  3. {
  4.    /**
  5.      * @var PDO
  6.      */
  7.    private $pdo = null;
  8.    private $tableName = "core_session";
  9.    public function __construct(PDO $pdo)
  10.    {
  11.        $this->pdo = $pdo;
  12.    }
  13.    
  14.    public function setTableName($tableName = "core_session")
  15.    {
  16.        $this->tableName = $tableName;        
  17.    }
  18.    
  19.    /**
  20.      * Stores session object
  21.      * @param $session
  22.      * @return boolean
  23.      */
  24.    public function storeSession( Framework_Session_Session $session )
  25.    {
  26.        try
  27.        {
  28.            $sql = "SELECT COUNT( id ) AS the_count FROM " . $this->tableName . " WHERE session_id = ?";
  29.            $statement = $this->createStatement($sql, array( $session->getID()));
  30.            $statement->execute();
  31.            $count = $statement->fetchColumn(0);
  32.            $statement->closeCursor();
  33.            
  34.            $sessionExists = ($count == 1); // 0 or 1 [unique session id]
  35.            if ( $sessionExists )
  36.            {
  37.                // update
  38.                $sql = "UPDATE " . $this->tableName . " SET updated_at = ?, data = ? WHERE session_id = ?";
  39.                $values = array( time(), serialize($session->getAllData()), $session->getID());
  40.                $statement = $this->createStatement($sql, $values);
  41.                $statement->execute();
  42.            }
  43.            else
  44.            {
  45.                // insert    
  46.                $sql = "INSERT INTO " . $this->tableName . " ( session_id, created_at, updated_at, data ) VALUES ( ?, ?, ?, ? )";
  47.                $values = array( $session->getID(), time(), time(), serialize($session->getAllData()));
  48.                $statement = $this->createStatement($sql, $values);
  49.                $statement->execute();
  50.            }
  51.            
  52.            return true;
  53.        }
  54.        catch ( PDOException $e )
  55.        {
  56.            return false;
  57.        }
  58.    }
  59.    /**
  60.      * Loads session object
  61.      * @param string $id ID of the session
  62.      * @return Framework_Session_Session
  63.      */
  64.    public function loadSession( $id )
  65.    {
  66.        try
  67.        {
  68.            $sql = "SELECT * FROM " . $this->tableName . " WHERE session_id = ?";
  69.            $statement = $this->createStatement($sql, array( $id ));
  70.            $statement->execute();
  71.            $row = $statement->fetch(PDOFETCH_ASSOC);
  72.            if ( ! $row )
  73.            {
  74.                return Framework_Session_SessionnewInstance($id);
  75.            }
  76.            else
  77.            {
  78.                $data = unserialize_utf8($row['data']);
  79.                return Framework_Session_SessionnewInstance($id, $data);                
  80.            }
  81.        }
  82.        catch ( PDOException $e )
  83.        {
  84.            // session does not exist, create new one
  85.            return Framework_Session_SessionnewInstance($id);
  86.        }
  87.    }
  88.    
  89.    /**
  90.      * Removed session identified by $id
  91.      */
  92.    public function removeSession( $id )
  93.    {
  94.        try
  95.        {
  96.            kill(); // XXX
  97.            $sql = "DELETE FROM " . $this->tableName . " WHERE session_id = ?";
  98.            $values = array( $id );
  99.            $statement = $this->createStatement($sql, $values);
  100.            $statement->execute();    
  101.            return true;
  102.           }
  103.        catch ( PDOException $e )
  104.        {
  105.            return false;
  106.        }
  107.    }
  108.    
  109.    /**
  110.      * @param string $sql
  111.      * @param array $values
  112.      * @return PDOStatement
  113.      */
  114.    private function createStatement($sql, $values = array())
  115.    {
  116.        $statement = $this->pdo->prepare($sql);
  117.        $i = 0;
  118.        foreach ( $values as $value )
  119.        {
  120.            $statement->bindParam( $i + 1, $values[$i] ); // DONT use value!!! as all fields have save value
  121.            $i++;
  122.        }
  123.        return $statement;
  124.    }
  125.    
  126. }    
  127. ?>


  1. <?php
  2. // przekazuje managerowi jakis obiekt klasy ktora implementuje interfejs Framework_Session_SessionStorage.
  3. // menadzera nie interesuje jaki to obiekt, ma tylko implementowac odpowiedni interfejs, czyli posiadac odpowiednie metody
  4. $sessionManager = new Framework_Session_SessionManager( new Framework_Session_FileSessionStorage( '/tmp/sessions' ) );
  5. ?>


Ten twoj kod ostatni - skasuj i nie patrz na niego wiecej, to cos strasznego, nie ma zadnego sensu, jest bledne itd.
Wybacz ze nie tlumacze czemu - ale po prostu caly kod jest bez sensu, chociaz sie kompiluje.

Co do metod statycznych:


Mam metody fabryczne (http://en.wikipedia.org/wiki/Factory_method_pattern )
public static function initWithEmailTemplateName($emailTemplateName){...}
public static function initWithEmailTemplate(EmailTemplate $emailTemplate){...}
sluzace do utworzenia nowego obiektu w rozny sposob, albo podajac obiekt, albo nazwe wg ktorej znajde sobie ten obiekt.
Do tego mam prywatny konstruktor, zeby po prostu go nie uzywac, tylko wlasnie tych metod.

Mozna by zrobic rozpoznawanie przekazanego parametru do konstruktora i robic to samo w konstruktorze, ale
nie pamietamy jakie parametry konstruktor przyjmuje, wlaczamy podpowiadanie i widzimy __construct( $emailTemplate )
i co mozemy tam wrzucic? e? musimy zajrzec do kodu, ew. przeczytac wiecej dokumentacji zeby sie dowiedziec ze
ten parametr moze przyjmowac obiekt albo stringa.
Co innego w np Javie, mozesz miec 2 konstruktory, jeden przyjmuje Stringa drugi EmailTemplate.

A moje metody same mi mowia jaki parametr mam podac, czy to string czy obiekt.

  1. <?php
  2. class Application_Email_SystemEmailSender
  3. {
  4.    private $senderName = '';
  5.    private $senderEmail = '';
  6.    /**
  7.      * @var EmailTemplate
  8.      */
  9.    private $emailTemplate = null;
  10.    private static $alreadyInitialized = false;
  11.    /**
  12.      * Data for filling the template
  13.      * @var array
  14.      */
  15.    private $data = array();
  16.    
  17.    private function __construct(EmailTemplate $emailTemplate)
  18.    {
  19.        $this->emailTemplate = $emailTemplate;
  20.        $this->initSettings();
  21.    }
  22.    
  23.    /**
  24.      * Loads deafult sender data
  25.      *
  26.      */
  27.    private function initSettings()
  28.    {
  29.        if ( self$alreadyInitialized )
  30.        {
  31.            return;
  32.        }
  33.        
  34.        $this->senderEmail = SystemSettinggetByName('email', 'sender_email')->getData();
  35.        $this->senderName = SystemSettinggetByName('email', 'sender_name')->getData();
  36.        
  37.        self$alreadyInitialized = true;
  38.    }
  39.    
  40.    /**
  41.      * Changes default sender data
  42.      *
  43.      * @param string $name
  44.      * @param string $email
  45.      */
  46.    public function setSender($name, $email)
  47.    {
  48.        $this->senderName = $name;
  49.        $this->senderEmail = $email;
  50.    }
  51.    
  52.    
  53.    
  54.    /**
  55.      * @param string $templateName
  56.      * @return Application_Email_SystemEmailSender
  57.      */
  58.    public static function initWithEmailTemplateName($emailTemplateName)
  59.    {
  60.        try
  61.        {
  62.            $emailTemplateSearch = new EmailTemplateSearch();
  63.            $emailTemplate = $emailTemplateSearch->findOneByName( $emailTemplateName );
  64.            $ses = new self($emailTemplate);
  65.            return $ses;
  66.        }
  67.        catch (DAO_RecordNotFoundException $e )
  68.        {
  69.            throw new Application_SystemEmailSenderException($e);
  70.        }
  71.    }
  72.    
  73.    /**
  74.      * @param EmailTemplate $emailTemplate
  75.      * @return Application_Email_SystemEmailSender
  76.      */
  77.    public static function initWithEmailTemplate(EmailTemplate $emailTemplate)
  78.    {
  79.        $ses = new self($emailTemplate);
  80.        return $ses;
  81.    }
  82.    
  83.    /**
  84.      * @param array $data
  85.      */
  86.    public function setData($data)
  87.    {
  88.        $this->data = $data;
  89.    }
  90.    
  91.    /**
  92.      * Sends email to User with previously set data
  93.      *
  94.      * @param User $user
  95.      */
  96.    public function sendEmailToUser(User $user)
  97.    {
  98.        // add user to data
  99.        $data = array_merge( $this->data, array( 'user' => $user ));
  100.        $subject = $this->emailTemplate->subject;
  101.        $body = $this->emailTemplate->getFilledBody($data);
  102.        
  103.        $senderName = $this->senderName;
  104.        $senderEmail = $this->senderEmail;
  105.        
  106.        $recipientEmail = $user->email;
  107.        $recipientName = $user->getFullName();
  108.        
  109.        $emailSender = new Framework_Libs_Email_SimpleEmailSender();
  110.        $emailSender->sendHTMLEmail($senderName, $senderEmail, $recipientName, $recipientEmail, $subject, $body );
  111.    }
  112. }
  113. ?>


Albo prosta klasa z prostymi uzytkowymi funkcjami, mozna by to tez niestatycznie zrobic, ale po co, potem bedziesz mial wiecej pisania:
  1. <?php
  2. $au = new AppUtils()
  3. $au->randomString( 5 );
  4. ?>


  1. <?php
  2. class AppUtils
  3. {
  4.    public static function randomString($length)
  5.    {
  6.        $chars = array_merge( range( "a", "z"), range( 'A', 'Z' ), range( 0, 9 ) );
  7.        shuffle( $chars );
  8.        $randomChars = array_slice( $chars, 0, $length );
  9.        return join( "", $randomChars );
  10.    }
  11. }
  12. ?>


Albo niesmierterlny singleton

  1. <?php
  2. class Framework_Language_LanguageManager
  3. {
  4.    private static $instance = null;
  5.    /**
  6.      * @return Framework_Language_LanguageManager
  7.      */
  8.    public static function getInstance()
  9.    {
  10.        if ( is_null( self$instance ))
  11.        {
  12.            self$instance = new self();
  13.        }
  14.        
  15.        return self$instance;
  16.    }
  17.    
  18.    private function __construct()
  19.    {
  20.        $this->languageLoader = new Framework_Language_LanguageLoader();
  21.        $this->loadAllLanguages();
  22.    }
  23.  
  24.    // ...
  25. }
  26. ?>


Wlasciwie to w wiekszosci te 3 typy statycznych metod mi wystarczyly.
marcio
Albo ja jestem tepy albo to jest takie "trudne".

Cytat
Ten twoj kod ostatni - skasuj i nie patrz na niego wiecej, to cos strasznego, nie ma zadnego sensu, jest bledne itd.
Wybacz ze nie tlumacze czemu - ale po prostu caly kod jest bez sensu, chociaz sie kompiluje.


Chcesz przez to powiedziec ze pierwszy kod jest lepszy lub obydwa sa do d....? smile.gif

Musze jeszcze nad tym posiedziec, znasz jakies ciekawe kursy etc ucze sie z tego z webcity i od gajdy plus ksiazka ale ciezko mi to idzie biggrin.gif.

Nie rozumiem tez takiej deklaracji:
  1. <?php
  2. public function finalizeSession( Framework_Session_Session $session  )
  3.  
  4. // i tego tez
  5. public function loadSession( $id )
  6.    {
  7.        $filename = $this->buildFilename( $id );
  8.        
  9.        if ( ! file_exists( $filename ))
  10.        {
  11.            return new Framework_Session_Session( $id );
  12.        }
  13.        
  14.        $serializedData = file_get_contents( $filename );
  15.        if ( $serializedData === FALSE )
  16.        {
  17.            return new Framework_Session_Session( $id );
  18.        }
  19.        
  20.        $data = unserialize( $serializedData );
  21.        if ( $data === FALSE )
  22.        {
  23.            return new Framework_Session_Session( $id );
  24.        }
  25.        
  26.        $session = Framework_Session_SessionnewInstance( $id, $data );
  27.        return $session;
  28.    }
  29. ?>

Czemu zwracasz obiekt w funkcji skoro go nie uzywasz?
dr_bonzo
/*
Eeee, yyyy, teraz dopiero zauwazylem ze tam sa 2 kody smile.gif

Wiec, oba sa do D.

Stworzenie nie moze implementowac Kot i Pies, bo to Pies i Kot sa bardziej szczegolowe (podgatunek) niz stworzenie (prosciej: znajdz mi takie COS co jest jednoczesnie psem i kotem, i jednoczesnie potrafi szczekac i mialczec)

moglbys to zrobic np tak:
  1. <?php
  2. interface Stworzenie
  3. {
  4.    public function dajGlos();
  5. }
  6.  
  7. class Kot implements Stworzenie
  8. {
  9.    public function zamialcz()
  10.    {
  11.        return "MiauUUUUUU!!";
  12.    }
  13.    
  14.    public function dajGlos()
  15.    {
  16.        return $this->zamialcz();
  17.    }
  18. }
  19.  
  20. class Pies implements Stworzenie
  21. {
  22.    public function zaszczekaj()
  23.    {
  24.        return "WUFFFF!";
  25.    }
  26.    
  27.    public function dajGlos()
  28.    {
  29.        return $this->zaszczekaj();
  30.    }
  31. }
  32. ?>

Kot i Pies maja to wspolnego ze potrafia "dac glos", ALE kazde z nich robi to po swojemu. I to jak robi jest w ich klasie zapisane, a nie w IF-ach

Polimorfizm:

  1. <?php
  2. $stworzenie = null;
  3. $stworzenia = array( new Kot(), new Pies() );
  4.  
  5. foreach ( $stworzenia as $stworzenie )
  6. {
  7.    echo $stworzenie->dajGlos(); // dziala bo obie klasy maja te metode
  8. }
  9. ?>



To jest zaprzeczenie OOP
  1. <?php
  2. // class Stworzenie
  3. function mial($kot, $halas) {
  4.  
  5. if(is_string($kot) && $kot == 'kot') return $halas;
  6.  
  7. else return 'Ta funkcja nie obsluguje halasu takiego zwoerzecia';
  8.  
  9. }
  10. }
  11. ?>


tylko klasa Kot ma miec mial(), bo to inaczej nie ma sensu, po co Psu metoda mial(). Wykonales dziedziczenie na odwrot.



Cytat
Musze jeszcze nad tym posiedziec, znasz jakies ciekawe kursy etc

Nie, ja sie uczylem z wielu ksiazek, i po hmm, 5 latach zalapalem oop biggrin.gif


Cytat
ublic function finalizeSession( Framework_Session_Session $session )

Czego tu nie rozumiesz? Framework_Session_Session sprawdza w czasie uruchomienia czy $session jest obiektem tej klasy, dodatkowo wspomaga system podpowiadania skladni w edytorze.


Cytat
Czemu zwracasz obiekt w funkcji skoro go nie uzywasz? (chodzi o loadSession())

Eeee? Yyy? no przeciez uzywam, zobacz gdzie jest wywolywane loadSession().

smile.gif
marcio
Jesli chcialbym dodac do twojego kodu funkcje z mojej klasy asbtr moglbym to zrobic z jej pomoca mam racje i dawac zamiast:
  1. <?php
  2. class Kot implements Stworzenie
  3. ?>

Tak:
  1. <?php
  2. class Kot extends wlasciwosci implements Stworzenie
  3. ?>


I tak implementacje funckji z klasy abtrs i tak samo dla klasy Pies?

EDIT:
Juz chyba lapie i wiem na czym polega moj blad, te 2 kody ktore podalem wyzej sa bledne na podstawie twojego mam 2 sposoby zeby dokonczyc klase.

1 sposob za pomoca interfejsow i klas normalnych:
  1. <?php
  2. interface Stworzenie
  3. {
  4.   public function dajGlos();
  5.   public function iq(); // skoro funckja jest wspolna dla klasy kot i pies ale ma inna implementacje
  6. }
  7.  
  8. class opis { // ta klasa jest normalna po niej beda dziedziczyc klasy kot i pies zeby nie pisac tych funkcji w kazdej klasie ktore je potrzebuja&nbsp:D
  9.  
  10. public function waga($waga) {
  11.  
  12. return $waga;
  13. }
  14.  
  15. public function wysokosc($wysokosc) {
  16.  
  17. return $wysokosc;
  18.   }
  19. }
  20.  
  21. class Kot extends opis implements Stworzenie {
  22.  
  23. public function zamialcz() {
  24.      
  25. return "MiauUUUUUU!!";
  26.   }
  27.  
  28. public function dajGlos() {
  29.      
  30. return $this->zamialcz();
  31.   }
  32.  
  33. public function iq() {
  34.  
  35. return rand(1,10);
  36.   }
  37. }
  38.  
  39. class Pies extends opis implements Stworzenie {
  40.  
  41. public function zaszczekaj() {
  42.      
  43. return "WUFFFF!";
  44. }
  45.  
  46. public function dajGlos() {
  47.      
  48. return $this->zaszczekaj();
  49.   }
  50.  
  51. public function iq() {
  52.  
  53. return rand(10, 50);
  54.   }
  55. }
  56. ?>

2 za pomoca interfejsow i klas abstr:
  1. <?php
  2. interface Stworzenie
  3. {
  4.   public function dajGlos();
  5. }
  6.  
  7. abstract class opis { // klasa rozszerzajaca funkcjami ogolnymi dla obydwoch klas i jedna wspolna z inna implementacja
  8.  
  9. abstract public function iq();
  10.  
  11. public function waga($waga) {
  12.  
  13. return $waga;
  14. }
  15.  
  16. public function wysokosc($wysokosc) {
  17.  
  18. return $wysokosc;
  19.   }
  20. }
  21.  
  22. class Kot extends opis implements Stworzenie {
  23.  
  24. public function zamialcz() {
  25.      
  26. return "MiauUUUUUU!!";
  27.   }
  28.  
  29. public function dajGlos() {
  30.      
  31. return $this->zamialcz();
  32.   }
  33.  
  34. public function iq() {
  35.  
  36. return rand(1,10);
  37.   }
  38. }
  39.  
  40. class Pies extends opis implements Stworzenie {
  41.  
  42. public function zaszczekaj() {
  43.      
  44. return "WUFFFF!";
  45. }
  46.  
  47. public function dajGlos() {
  48.      
  49. return $this->zaszczekaj();
  50.   }
  51.  
  52. public function iq() {
  53.  
  54. return rand(10, 50);
  55.   }
  56. }
  57. ?>


Co do 2 sposobu zamiast robic interfejs funkcje dajGlos() moglem dac do klasy asbtr. opis ale to tylko przyklad z uzyciem obydwoch biggrin.gif czy juz cos zaczynam rozumiec, czy to juz lepiej wyglada od tych wczesniejszych kodow?


Good?
dr_bonzo
Tak lepiej.

Cytat
Co do 2 sposobu zamiast robic interfejs funkcje dajGlos() moglem dac do klasy asbtr

Wlasnie mialem to napisac smile.gif Ze 1 klasa abtr. byla by najwlasciwsza w tym przypadku. Stworzenie z waga, wzrostem itp.
marcio
@Dr_bonzo czy moglbys mi podac przyklad jakiejs klasy z uzyciem klas abstr albo interefjsow taki jaki ci przychodzi do glowy a ja sproboje go napisac zobaczymy co z tego wyjdzie..

P.S plusa dam ci pozniej bo ludzie jak widza ze w temacie jest juz plus to nawet do niego nie zagladaja
Crozin
  1. <?php
  2. abstract class rower{
  3.  private
  4.    $predkosc = 0,
  5.    $bieg = 1;
  6.  
  7.  public function przyspiesz($predkosc){
  8.    $this->predkosc += (int) $predkosc;
  9.  }
  10.  
  11.  public function zwolnij($predkosc){
  12.    $this->predkosc -= (int) $predkosc;
  13.  }
  14.  
  15.  public function ustawBieg($bieg){
  16.    $bieg = (int) $bieg;
  17.    if($bieg < 1 || $bieg > 6){
  18.      throw new Exception('Niewlasciwa wartosc biegu');
  19.    }
  20.  
  21.    $this->bieg = $bieg;
  22.  }
  23.  
  24.  abstract public function predkosc();
  25. }
  26.  
  27. class rowerGorski extends rower{
  28.  public function predkosc(){
  29.    //pseudo-wzor
  30.    return pow($this->predkosc, $this->bieg)
  31.  }
  32. }
  33.  
  34. class rowerMiejski extends rower{
  35.  public function predkosc(){
  36.    //pseudo-wzor
  37.    return $this->predkosc * $this->bieg;
  38.  }
  39. }
  40. ?>
Jak widzisz zarówno rowerMiejski (tak one się nazywają? biggrin.gif) jak i rowerGórski to rowery... mają cześć identycznych zachowań/stanów (zmiejsz predkosc, zwieksz, zahamuj, skrec/60km/h, 100obr/min) ale pod pewnymi wzgledami sie roznia. Z drugiej strony nie można stworzyć obiektu klasy rower bo każdy rower jest jakimś wyspecializowanym typem.

Teraz przykład na interfejs
  1. <?php
  2. interface Sessionable{ //taki wyraz pewnie nawet nie istnieje, ale mi tu pasuje, a polskiego odpowiednika nie znam:P
  3.  public function save();
  4.  public function read();
  5. }
  6.  
  7. class SesjaZBazy implements Sessionable{
  8.  private
  9.    $sesja = array();
  10.  
  11.  public function save(){
  12.    mysql_query(sprintf('UPDATE sesje SET dane = "%s" WHERE idUzytk = 123;', serialize($this->sesja)));
  13.  }
  14.  
  15.  public funcion read(){
  16.    $this->sesja = unserialize($this->pobierzDane());
  17.  }
  18.  
  19.  private function pobierzDane(){
  20.    $r = mysql_query('SELECT dane FROM sesje WHERE idUzytk = 123;');
  21.    return mysql_fetch_array($r, MYSQL_ASSOC);
  22.  }
  23. }
  24.  
  25. class SesjaZPliku implements Sessionable{
  26.  private
  27.    $sesja = array();
  28.  
  29.  public function save(){
  30.    file_put_contents('123.sesja.php', serialize($this->sesja));
  31.  }
  32.  
  33.  public funcion read(){
  34.    $this->sesja = unserialize(file_get_contents('123.sesja.php'));
  35.  }
  36. }
  37. ?>
marcio
W sumie kazdy z kodow powyzej mozna by napisac za pomoca klas abstr jak i interfejsow jak dobrze widze biggrin.gif

Jednak czy ktos moglby mi dac jakies zadanie tzn klase do napisania ja napisze i podam kod zobaczym co z tego wyjdzie wiem ze moze glupio sie zapytac o takie cos ale tak sie szybko naucze a sam nie wiem co wymyslic smile.gif.

I czy ktos moze mi wytlumaczyc kiedy podaje sie jako argument do funkcji jakis obiekt np w tym kodzie:
  1. <?php
  2. public function finalizeSession( Framework_Session_Session $session  )
  3. ?>

Po co tak robic?
Crozin
Zawsze początkującym mówię: napisz zestaw klas do obsługi DOM winksmiley.jpg
Możesz się posłużyć JS jako "efektem docelowym"

Kod
var myAElement = document.createElement('a');
myAElement.setAttribute('href', 'http://php.pl');

var myDivElement = document.createElement('div');
myDivElement.appendChild(myAElement);
Dodaj do tego obsługę atrybutów i generalnie częsci (nie pisz wszystkiego - to tylko przykładowa praca ma być) tego co się przydaje przy obsłudze DOM.
Cytat
I czy ktos moze mi wytlumaczyc kiedy podaje sie jako argument do funkcji jakis obiekt np w tym kodzie:
Kiedy chcemy, aby dany argument był obiektem, który:
Jest instancją wskazanej klasy i/lub dziedziczy po niej i/lub implementuje taki interfejs.
Shili
Cytat
W sumie kazdy z kodow powyzej mozna by napisac za pomoca klas abstr jak i interfejsow jak dobrze widze
Niekoniecznie. A raczej nie opłaca się ich przepisywać z interfejsu na klasę abstrakcyjną czy odwrotnie.

W interfejsie nie zdefiniujesz żadnej metody ani właściwości. Interface to taki zbiór metod publicznych, które klasa musi implementować, a każda z klas implementujących interface może to robić zupełnie, ale to zupełnie inaczej. W klasie abstrakcyjnej możesz jak najbardziej implementować metody (nie tylko publiczne) i nadawać właściwości. Ale oczywiście możesz tylko je inicjować, bez implementacji winksmiley.jpg

Wyobraź sobie, że na przykład masz w sprzedaży ulotki i książki.
Jedno i drugie ma:
czytaj()
porwij()

ale więcej wspólnego nie mają - zero cech wspólnych, zero metod wspólnych (w metodzie porwij dla ulotki rwiesz jedną stronę, dla książki strona po stronie, podobnie dla czytaj), mają też inne właściwości (ulotka kolor tła, a książka ilość stron). Jak byk pasuje tutaj interfejs.

Ale wyobraź sobie, że zamiast ulotek masz czasopisma.
Mają te same metody
czytaj()
porwij()
te same właściwości:
ilość stron
cena
różnią się nieznacznie (ogólnie, jednak się różnią)

i nie ma sensu robić tutaj interfejsu, skoro tak samo implementują pewne rzeczy. Jak znalazł klasa abstrakcyjna, jeśli oczywiście chcesz wymusić, żeby nie można było zainicjować takiej klasy (nazwijmy ją sobie Czytadło). W końcu nie wskazuje ona na konkretny obiekt po wywołaniu winksmiley.jpg

Albo powiedzmy sobie, że mają jedną metodę xxx() którą obie muszą zaimplementować, ale implementują ją różnie - brak mi pomysłu na sensowny przykład. Wtedy metodę robisz abstrakcyjną, klasę abstrakcyjną i abstrakcja ma już sens.

Czy jest sens pisać dom?
Jak najbardziej. Dodałabym do tego tylko prywatną, czy też chronioną metodę do każego obiektu sprawdzającą czy jest sens zrobić appendChild (do inputa nie wciśniesz diva, w ogóle nic nie wciśniesz). Poza tym faktycznie fajne ćwiczenie.
Crozin
Cytat
ak najbardziej. Dodałabym do tego tylko prywatną, czy też chronioną metodę do każego obiektu sprawdzającą czy jest sens zrobić appendChild (do inputa nie wciśniesz diva, w ogóle nic nie wciśniesz). Poza tym faktycznie fajne ćwiczenie.
Generalnie ja bym proponował zrobić:
  1. <?php
  2. abstract class HTMLElement{
  3.  protected
  4.    $tagName = '',
  5.    $attributes = array(),
  6.    $childNodes = array(),
  7.    $possibleAttributes = array('*'),
  8.    $possibleChilds = array('*');
  9.  
  10.  //methody do operowania na powyższych polach, n:
  11.  public function appendChild(HTMLElement $child){
  12.    if($this->possibleChilds === false || array_search($child->getTagName(), $this->possibleChilds) === false){
  13.      throw new Exception(sprintf('The <%s> element cannot contains <%s> element.', $this->getTagName(), $child->getTagName()));
  14.    }
  15.  
  16.    $this->childNodes[] = $child;
  17.  }
  18.  
  19.  public function getTagName(){
  20.    return $this->tagName;
  21.  }
  22. }
  23.  
  24. abstract class HTMLSelfClosedElement extends HTMLElement{
  25.  protected
  26.    $possibleChilds = false;
  27. }
  28.  
  29. class FormElement extends HTMLElement{
  30.  //...
  31. }
  32.  
  33. class InputElement extends HTMLSelfClosedElement{
  34.  //...
  35. }
  36.  
  37. $form = new FormElement();
  38. $input = new InputElement();
  39.  
  40. $form->appendChild($input);
  41. ?>
Shili
Proponowałam prywatną ze względu na jedno z rozróżnień interfejsu z klasą abstrakcyjną. Oczywiście, jak najbardziej się zgadzam z zaprezentowanym rozwiązaniem, jednak w przypadku metody chronionej, tudzież prywatnej marcio by własnoręcznie zobaczył, że jednak nie każdą klasę abstrakcyjną da się zamienić na interfejs. Tego aspektu zabrakło mi osobiście w tym temacie winksmiley.jpg chociaż przyznam, że jak najbardziej mogłam coś przeoczyć winksmiley.jpg
marcio
Ok dzieki ze mi tak tlumaczycie jestescie na medal jednak nie znam js i szczerze mowiaz nigdy nie interesowalem sie dom moze jednak cos innego moglbym napisac?
Shili
To załóżmy, że robisz system domu.
Na samej górze jest działka.
Na działce mogą stać bezpośrednio tylko dom, garaż i ogród.
Samochód może stać jedynie w garażu i ogrodzie.
Lampa może stać w domu, garażu i ogrodzie.
Łóżko tylko w domu.
Pudełko może stać wszędzie, a w pudełku może w dodatku być lampa i łóżko (pudełko jest duże).
Człowiek może sobie być w domu, w garażu, w ogrodzie, w samochodzie, w łóżku, w pudełku (jest duże), ale nie może być w lampie.

Trochę skomplikowane, ale to taki DOM w wydaniu domowym.
Wszystkiemu możesz nadawać "atrybuty", tak jak w przypadku html: mogą być to i po części te same (waga) i różne - kolor oczu dla człowieka, a kapy dla łóżka.
Wszystko ma pewne metody wspólne.

Nie wiem czy pasuje, na szybko wymyśliłam coś w tym stylu, żeby było analogicznie winksmiley.jpg
marcio
Cytat(Shili @ 15.09.2008, 22:55:57 ) *
To załóżmy, że robisz system domu.
Na samej górze jest działka.
Na działce mogą stać bezpośrednio tylko dom, garaż i ogród.
Samochód może stać jedynie w garażu i ogrodzie.
Lampa może stać w domu, garażu i ogrodzie.
Łóżko tylko w domu.
Pudełko może stać wszędzie, a w pudełku może w dodatku być lampa i łóżko (pudełko jest duże).
Człowiek może sobie być w domu, w garażu, w ogrodzie, w samochodzie, w łóżku, w pudełku (jest duże), ale nie może być w lampie.

Trochę skomplikowane, ale to taki DOM w wydaniu domowym.
Wszystkiemu możesz nadawać "atrybuty", tak jak w przypadku html: mogą być to i po części te same (waga) i różne - kolor oczu dla człowieka, a kapy dla łóżka.
Wszystko ma pewne metody wspólne.

Nie wiem czy pasuje, na szybko wymyśliłam coś w tym stylu, żeby było analogicznie winksmiley.jpg


No no no myslalem ze bedzie to cos bardziej hmm... "normalnego" np nie wiem ksiega gosci czy cos obsluga plikow albo nie wiem ale jak mam sie nauczyc to i to jest dobre jutro zabiore sie za kodzenie bo za nieglugo ide spac
mike
Programowanie obiektowe to sposób przedstawiania świata w określony sposób. Sposób postrzegania i myślenia. Załapiesz to co podała ~Shili to możesz pisać księgę gości.
Inny przykład OOP: zamodeluj obiektowo akwarium i to co się w nim znajduje.
Shili
Próbowałam dać coś podobnego do wcześniej omawianego przez Crozine'a przykładu, żeby jechać tą samą linią winksmiley.jpg

Tylko nie za bardzo wiem jak w księdze gości chciałbyś implementować w sensowny sposób interfejsy czy klasy abstrakcyjne.
Tutaj masz bardzo dużo obiektów na samym wstępie i aż się one proszą o zastosowanie interfejsu lub klasy abstrakcyjnej (które - jak najbardziej zostawiam Tobie - najlepiej zrobić moim zdaniem na jednym i drugim, być może na obu naraz (oczywiście jeśli ma się wystarczająco dużo czasu i chęci) i stwierdzić empirycznie co lepsze - ja bardziej się uczę na "błędach" niż na teorii). Jednak jeśli myślisz, że coś bardziej konwencjonalnego będzie lepsze, to rób to jak najbardziej! biggrin.gif

@down
Jestem kobietą tongue.gif
marcio
Cytat
ja bardziej się uczę na "błędach" niż na teorii

Racja i dlatego napisze to co podales w przykladzie albo przynajmniej sproboje napisac
Crozin
Skoro nie znasz to tym lepiej - zobacz tylko w wiki ogólnie "Z czym się DOM je" i bierz się za pisanie winksmiley.jpg
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.
Invision Power Board © 2001-2025 Invision Power Services, Inc.