![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 550 Pomógł: 9 Dołączył: 29.05.2009 Skąd: Ostrów Wielkopolski Ostrzeżenie: (0%) ![]() ![]() |
Witam,
nie umiem ogarnąć konstruktora kiedy go używamy i po co? Może ktoś mi wytłumaczy? W poniższym przykładzie mamy klasę dog w której mamy publiczny dostęp do atrybutu $name oraz konstruktora. Z tego co rozumiem konstruktor jest to metoda która w chwili powstania obiektu nadaje mu jakiś właściwości? Ale po co i kiedy tego mam używać? klasa Kod <?php class Dog{ public $name;//atrybut przechowujący imię psa /*konstruktor*/ public function __construct($name){ $this->name = $name; } public function roar(){ echo 'chał chał'; } //ciach } ?> obiekt Kod <?php
require('class.dog.php'); $reksio = new Dog('Reksio'); echo $reksio->name; //atrybut "name" publiczny, więc wyświetlone zostanie 'Reksio' $reksio->roar(); //metoda roar() publiczna, więc wyświetlone zostanie 'chał chał' ?> |
|
|
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 690 Pomógł: 92 Dołączył: 6.02.2011 Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 550 Pomógł: 9 Dołączył: 29.05.2009 Skąd: Ostrów Wielkopolski Ostrzeżenie: (0%) ![]() ![]() |
Już miej więcej się domyśliłem, że konstruktora używamy do takich akcji jak np: połączenia się z bazą danych podanie nazwy użytkowanika, hasło.
Incjalizujemy połączenie z bazą danych. Tak? |
|
|
![]()
Post
#4
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Ech... Konstruktor to SPECJALNA metoda, która ZAWSZE sama się uruchamia, gdy tworzony jest obiekt tej klasy. Jeśli więc ma ona posiadać jakieś wartości od razu na starcie, to używamy do tego konstruktora. Klasa bowiem sama nie powinna mieć z góry ich narzuconych, czyli:
to błąd, gdyż powinno być:
-------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
@thek: A to niby czemu coś takiego miałoby być błędem?
Zadaniem konstruktora jest przygotowanie obiektu do pracy. W nim wykonuje się to wszystko co jest potrzebne do tego by obiekt w ogóle był zdatny do użytku. Przykładowo jeżeli mielibyśmy obiekt typu File moglibyśmy w konstruktorze jako argument podać URL (np. ścieżkę w systemie plików) pliku. Taki konstruktor mógłby pobrać od razu informacje o tym czy plik już istnieje. Przez konstruktor możemy przekazać też różne dane, które są potrzebne do działania obiektu, przykładowo może to być wspomniany obiekt pozwalający na komunikację z bazą danych. |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 550 Pomógł: 9 Dołączył: 29.05.2009 Skąd: Ostrów Wielkopolski Ostrzeżenie: (0%) ![]() ![]() |
Odbiegając od tematu ciężko się nauczyć mi osobiście początkującemu programiście Programowani obiektowego z kliku powodów:
1)- korzystam z książki Zaaansowane programowanie plus , http://pl.wikibooks.org/wiki/PHP/Czym_jest...ie_obiektowe%3F, http://php.pl/phppl/Wortal/Artykuly/PHP/Po...lasa-Co-to-jest, http://php.pl/Wortal/Artykuly/PHP/Podstawy...poczatkujacych5 w każdym źródle wiedzy jest to trochę inaczej opisane ... ![]() 2) na początku programowałem strukturalnie, i teraz natłok nowych pojęć też jest barierą 3) nie mam kontaktu z żadnym koderem, który zarabia pisząc w ten sposób Ale to tak tylko napisałem od siebie ![]() Pozdrawiam |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 782 Pomógł: 153 Dołączył: 21.07.2010 Ostrzeżenie: (0%) ![]() ![]() |
@Crozin - błąd nie ale thek ma trochę racji, w podejściu do domyślnych właściwości obiektów jest trochę niekonsekwencji. Np. mogę im przypisać w deklaracji typ prosty ale już nie złożony obiekt (co jest sensowne, choć niekonsekwentne). I te ostatnie inicjuje się w konstruktorach. Jak dla mnie to co powiedział thek jest po prostu konsekwentnym stosowaniem pewnej zasady.
-------------------- Już mi się ani wiedzieć, ani tym bardziej myśleć nie chce.
[Think different]! |
|
|
![]()
Post
#8
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Może wyjaśnię o co mi chodzi, bo everth "widzi" o co mi biega
![]() ![]() EDIT: Byłbym zapomniał... Osobiście czasem naginam to i mam jeden, jedyny wyjątek od tej reguły: stała i niezmienna wartość mająca być widoczna dla wszystkich obiektów danej klasy. Coś widocznego tylko dla tejże klasy i zazwyczaj też staram się tę zmienną zabezpieczyć przed przypadkowym nadpisaniem stosując const ![]() -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
@thek: jak zwykle nie zawiódł. Ładny wywód i trzykrotne odejście od tematu zamiast krótkiej i precyzyjnej odpowiedzi.
![]() Rozumiem co masz na myśli, nie mniej jednak trudno mi się w pełni zgodzić ponieważ nie dostrzegam jakiś zagrożeń czy niedogodności związanych z bezpośrednim definiowaniem wartości przy deklaracji właściwości obiektu (pomijamy tutaj aspekt kolejnej ułomności PHP, które pozwala tylko na przypisanie prostych wartości). Dlatego proszę o podanie jakiegoś przykładu demonstrującego. Napisałeś, że przypisywanie domyślnych wartości to zadanie obiektu, nie klasy. Trzeba jednak pamiętać jaka jest kolejność działań interpretera przy tworzeniu obiektu (tutaj akurat odniesienie do Javy ale jestem niemalże pewien, że PHP działa dokładnie tak samo - niestety nie da się w nim tego tak łatwo sprawdzić). 0. Uruchomienie bloku static - w PHP tego nie ma. 1. Utworzenie obiektu. 2. Zainicializowanie wszystkich właściwości. 3. Uruchomienie konstruktora. ( http://ideone.com/XPG8N ) Także przypisanie domyślnych wartości bezpośrednio przy ich deklaracji można w przypadku obiektów traktować jako prosty "skrót". Bo w sumie działa to tak jakbyś te przypisania dał na sam początek konstruktora. Jednakże tak jak napisałem, proszę o jakiś przykład gdzie takie postępowanie mogłoby prowadzić do jakiś problemów. Przykład nie koniecznie musi być z PHP. |
|
|
![]()
Post
#10
|
|
![]() Grupa: Zarejestrowani Postów: 550 Pomógł: 9 Dołączył: 29.05.2009 Skąd: Ostrów Wielkopolski Ostrzeżenie: (0%) ![]() ![]() |
Stworzyłem klasę, która łączy się z bazą oraz pobiera dane.
klasa: Kod <?php class database { private $id; private $name; private $description; private $age; private $con; public function __construct($widgetID) { $this->con = mysql_connect("localhost","root",""); if (! is_resource($this->con)) { throw new Exception('Could not connect: ' . mysql_error()); } $db_selected = mysql_select_db("my_db", $this->con); if (!$db_selected) { die ('Nie można ustawić foo : ' . mysql_error()); } $sql = mysql_query("SELECT * FROM Persons WHERE personID='$widgetID'"); if(! is_resource($sql)) { throw new Exception("Błąd przy wykonywaniu instrukcji wyboru"); } $data = mysql_fetch_array($sql); $this->id = $widgetID; $this->name = $data['FirstName']; $this->description = $data['LastName']; $this->age = $data['Age']; } public function getName() { return $this->name; } public function getDescription() { return $this->description; } public function getAge() { return $this->age; } public function __destruct() { mysql_close($this->con); } } ?> Wyświetlenie danych: Kod <?php require_once('class.database.php'); try { $objWidget = new database(2); print "Imie: ". $objWidget->getName() . "<br>\n"; print "Nazwisko: ". $objWidget->getDescription() . "<br>\n"; print "Wiek: ". $objWidget->getAge() . "<br>\n"; } catch(Exception $e) { die("Wystąpił problem: " . $e->getMessage()); } ?> Wydaje mi się że kod jest poprawny. Teraz mogę sobie dodać tutaj dodawanie, edytowanie oraz usuwanie danych ![]() Co do konstruktora, rozumiem że jest on uruchamiany w momencie stworzenia obiektu czyli od razu jesteśmy połączeni z bazą danych, Kod $objWidget = new database(2); i mamy ustawioną właściwość 2 czyli wiersz w bazie na którym chcemy pracować. Ten post edytował cykcykacz 21.04.2011, 19:13:46 |
|
|
![]()
Post
#11
|
|
![]() Grupa: Zarejestrowani Postów: 690 Pomógł: 92 Dołączył: 6.02.2011 Ostrzeżenie: (0%) ![]() ![]() |
W konstruktorze nie robimy zwykle takich rzeczy jak mysql_query, mysql_fetch_assoc etc., przerzuca się to do innych funkcji w klasie
Ten post edytował mat-bi 21.04.2011, 19:21:55 |
|
|
![]()
Post
#12
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Spróbuj w C/C++ tak zrobić, to kompilator Ci się na starcie od razu oburzy. Język ten nie pozwala mieszać definicji, deklaracji i inicjalizacji w wielu wypadkach w jeden wielki mix. Ogólnie nie jest to jakiś błąd, który powowdowałby problemy, ale przypuśćmy, że można w klasie na etapie definicji podać i przypisać jako własność składową wskaźnik/uchwyt do pliku. Dajmy na to o składni fopen('nazwa.rozszerzenie', 'w'); i nie wiem czy zauważysz co się wtedy dzieje gdy zechcemy zmienić plik w późniejszym etapie... Plik zostanie otwarty, wyczyszczony i będzie czekał. Jeśli w tym momencie zechcesz zmienić plik otwarty na inny to mamy bajzel poprzez otwarty niewłaściwy plik, na dodatek jest on wyzerowany flagą "w" i musimy najpierw go zamknąć zanim tej właściwości przypiszemy wskaźnik do nowego pliku. A tak moglibyśmy nazwę pliku podawać dopiero na etapie konstruktora, przy czym jakiś plik byłby domyślny. Rozwiązanie znacznie bardziej eleganckie. Oczywiście PHP na fopen i przypisanie uchwytu do pliku w deklaracji klasy nie pozwala ( właściwie to nie testowałem tego, ale zapewne nie pozwala
![]() ![]() Mat-bi...Czemu nie? Klasa Database, która jako statyczną własność "trzymie" identyfikator połączenia to nie jest takie złe rozwiązanie. Potem jej tylko używasz gdzie chcesz, nie martwiąc się o nic ![]() Oczywiście mówię tu tylko o ustanowieniu ,skonfigurowaniu połączenia w konstruktorze i nic więcej. -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 782 Pomógł: 153 Dołączył: 21.07.2010 Ostrzeżenie: (0%) ![]() ![]() |
Tak mnie naszło - czy PHP w trakcie inicjowania obiektów rzeczywiście inicjuje wszystkie właściwości? Czy może robi to w momencie pierwszego odwołania do nich? Bo w zasadzie klasa może być przez PHP inicjowana jako "czysta" - skoro można dynamicznie dodawać właściwości to dlaczego wymuszać ich alokację w momencie tworzenia obiektu?
W takim wypadku przestaje mieć znaczenie gdzie nastąpi zainicjowanie właściwości obiektu - czy w definicji klasy, czy w konstruktorze - i tak realnie nastąpi to w momencie użycia. Pozostaje więc jedynie kwestia formalna (czyli że klasa to szablon struktury i nie powinna zawierać danych) -------------------- Już mi się ani wiedzieć, ani tym bardziej myśleć nie chce.
[Think different]! |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
@thek: A jakiś argument przeciw, ale nie bazujący na błędnym kodzie? Bo pokazałeś przykład, gdzie jako domyślne wstawia się coś co w cale nie musi być domyślne czy też "wymagane".
@everth: Musiałbyś albo zgłębić źródła albo zrobić jakieś testy (np. zużycia pamięci), ale obstawiam, że przy tworzeniu obiektu tworzone są od razu wszystkie właściwości, a ich wartości są inicjowane. |
|
|
![]()
Post
#15
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Czy ja wiem czy takie nie domyślne? Mam klasę w Kohanie, która loguje różne operacje nie będące błędami aplikacji, ale niedozwolonymi użytkownikowi (próby ataków głównie) i domyślnie ona zapisuje do tego samego pliku zawsze. Oczywiście gdyby php na to pozwalał, mógłbym od razu uchwyt do pliku walnąć przy definicji i to jest ta sytuacja, o której pisałem. Teoretycznie nie byłby to błąd, ale z automatu pojechaliśmy ostro po jej reusability. Co do niedogodności, to można by nieco zahaczyć o "widoczność". Użytkownik/programista bez spoglądania do wnętrza klasy nie będzie świadom istnienia tej właściwości i jej wartości. Zostaje ona bowiem ustawiona bez jego udziału. Jeśli na etapie tworzenia obiektu od tej własności może zależeć jakiś wynik, to sytuacja ta może prowadzić do zafałszowanych rezultatów. Przykład z plikami jest tutaj dobry ponieważ próba wywolania choćby po raz drugi obiektu zwróci wartość nieoczekiwaną. Pierwsza instancja zwinie plik i go zablokuje, a druga będzie próbowała dobrać się do zablokowanego pliku i zrobi zonka i zakleszczy się lub co gorsze - nadpiszą swoje wyniki, bo przecież użytkownik nie wie z jakim plikiem i w jakim trybie otwarcia ma do czynienia. Informacje te powinien sam użytkownik jawnie podać w konstruktorze. Problem mogą sprawić zadeklarowane wartości dla właściwości statycznych, które przecież choć wspólne dla klasy mogą mieć w wyniku działania programu inną wartość niż zadeklarowana w klasie, co będzie mylące podczas analizy kodu. Ogólnie właśnie zmienne statyczne to jest tutaj możliwe źródło pomyłek.
-------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#16
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Temat wiąże się z OOP więc proszę mi tutaj Kohany nie mieszać...
![]() A wracając do tematu, podany przez Ciebie przykład nie powinien nigdy w ogóle się pojawić. Przecież coś tak "dynamicznego" jak ścieżka do jakieś pliku może nawet nie być jednolita w obrębie jednego projektu - o różnych nie wspominając. Temat dotyczy takich sytuacji:
I trzeba rozróżnić to co w ogóle może być domyślne, od tego co jest bardziej "dynamiczne" i nie ma wartości domyślnej:
|
|
|
![]()
Post
#17
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
[offtop]No nie mów, że Kohana to nie OOP?
![]() ![]() Co do przykładu to akurat bardziej miałem na myśli sytuację, gdzie własność może być różnego typu i jej ustawienie jest na poziomie tworzenia obiektu. Przykładowo poprzez różne wersje konstruktora inicjalizuje się ona raz obiektem, raz tablicą, a raz skalarem lub w sytuacji bardziej subtelnej - reaguje inna wartością tego samego typu na tworzenie z poziomu www i CLI. -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#18
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Ale przecież oczywistym jest, że jeżeli ustalenie czegoś nie jest tak trywialne, nie stosuje się wartości domyślnych. Tutaj mowa jest o przypadkach, gdy domyślna wartość jest używana przykładowo wyłącznie na potrzeby obiektu (patrz przykład z Randomem) czy też jej zmiana nie niesie za sobą żadnych komplikacji (patrz przykład ze stanem użytkownika czy poziomem zapisywanych błędów).
Tak więc czy poza jakąś niezbyt jasną i mało popularną konwencją w przykładach z klasami User i Logger z mojego wcześniejszego postu jest coś nie tak? Czy preferowany przeze mnie pierwszy zapis może prowadzić do czegoś "niewygodnego"? Cytat [offtop]No nie mów, że Kohana to nie OOP? Ja rozumiem, że to nie MVC, ale akurat OOP można ją nazwać [/offtop] Nie będziemy ciągnąć tutaj kolejnego offtopicku - zapraszam na PW / nowy wątek - ale mogę się zgodzić na nazwanie Kohany frameworkiem OOP gwałcącym większość podstawowych zasad OOP. ![]() |
|
|
![]()
Post
#19
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Cytat jeżeli ustalenie czegoś nie jest tak trywialne, nie stosuje się wartości domyślnych To akurat sprawa dyskusyjna. Dla różnych osób różne rzeczy mogą być trywialne ![]()
jak i są nieprawidłowe, gdyż na sztywno ustawiają albo w klasie albo w obiekcie pewne wartości, a jak wspomniałem, powinny one być do obiektu przekazane z zewnątrz, tak więc metodą poprawną byłoby użycie: gdyż zarowno klasa nie zna wybranego poziomu obiektu, jak i do czasu utworzenia instancji oraz wywołania konstruktora także nie jest to narzucane, a dodatkowo nie modyfikujemy logiki samego konstruktora specjalnie pod przypadek domyślny. Niezależnie czy wywołany zostanie konstruktor domyślny czy nie, zostanie on obsłużony identycznie, gdyż różnić się będzie jedynie parametrami. To co jest w php a co Ty popierasz, to zwyczajnie przesunięcie tego parametru domyślnego z listy wprost do definicji, co według mnie nagina w pewien sposób abstrakcyjność klasy. EDIT: Byłbym zapomniał... Wątku o OOP w przypadku Kohany i wszelkich frameworków nie musimy ruszać, gdyż chyba oboje jesteśmy świadomi, że chyba każdy go w mniejszym lub większym stopniu narusza ![]() -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#20
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Ależ Ty mącisz...
![]() W obu przypadkach jak Ci nie pasuje domyślne ustawienie pokrywające powiedzmy 90% przypadków użycia możesz zmienić sobie poziom logowany błędów:
Uznałeś, że drugi zapis jest przynajmniej częściowo niepoprawny. Ja się pytam dlaczego? Jakie niebezpieczeństwa czy problemy mogą wynikać z takiego zapisu? Cytat EDIT: Byłbym zapomniał... Wątku o OOP w przypadku Kohany i wszelkich frameworków nie musimy ruszać, gdyż chyba oboje jesteśmy świadomi, że chyba każdy go w mniejszym lub większym stopniu narusza Każdy większy projekt ma jakieś delikatne defekty. Nie da się napisać kodu doskonałego z jakąś tam ideologią. Ale nie każdy projekt tak gwałci OOP jak Kohana.
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 7.06.2025 - 17:43 |