Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: słowa kluczowe parent, self.. brakuje mi jednego :)
Forum PHP.pl > Forum > PHP
Nalfein][WR
[php:1:9afb1fe096]
class AbstractSingleton
{
static function instance()
{
static $instance;
if (!$instance)
{
// nie mogę napisać $this, bo metoda jest statyczna
$class = self::getClassName();
$instance = new $class;
}
return $instance;
}



}


class test extends AbstractSingleton
{
function getClassName() {
return 'test'; // edit: skądś tutaj wziąłem 'test2'
}
}

test::instance();
[/php:1:9afb1fe096]

wywala błąd:

Fatal error: Call to undefined method abstractsingleton::getclassname() in E:usrwwwssiindex.php on line 12

Testowałem na PHP5 b2 i b3, z i bez słowa kluczowego "static" na początku metody. Podmieniałem self na $this, this i bez skutku.

Niby dobrze, bo self:: służy do wywołania metody klasy w której jestem, używa się jej przy nadpisywaniu. Wobec tego jakiego słowa mam użyć zamiast "self", jest jakiś odpowiednik $this bez "$" do użycia w metodach statycznych?
bamboos
Witam!!
Zupełnie się nie znam na programowaniu obiektowym w php5, ale skoro istnieje parent, to może też child? Ale wątpie!?!
DeyV
Przy takim zapisie wydaje mi się, ze możliwe jest odowoływanie się tylko do metod dostępnych w danej klasie, lub w którymś z jego przodków.
Nie obowiązuje to w drugą stronę, mimo że dana metoda byłaby dostępna w obiekcie utworzonym w nalogiczny sposób.
Nalfein][WR
No własnie. Brakuje takiego słowa w stylu "final", które umożliwiałoby dostęp do "finalnej", końcowej klasy na rzecz której byłaby wywoływana ta metoda.

Bez tego jest głupio. Bo załóżmy, że mamy klasę Aplikacja, której chcemy mieć tylko jeden obiekt, więc dodajemy do niej takie coś jak ta metoda ::instance(), w której tworzymy za pomocą "new Aplikacja" ten nowy obiekt tak jak w kodzie powyżej. Teraz wprowadzamy pewną zmianę/rozszerzenie/mod do klasy Aplikacja, ale jak szkoła OO uczy, nie modyfikujemy istniejącego kodu, lecz tworzymy nową klasę RozszerzonaAplikacja dziedziczącą z Aplikacji. Implementujemy nowe zachowanie i myślimy, że będzie wszystko działać OK. Otóż nie - otóż w Aplikacja::instance() napisaliśmy "new Aplikacja", więc gdy wywołamy RozszerzonaAplikacja::instance(), metoda ::instance() zwróci nam obiekt Aplikacja. Nie możemy napisać "new get_class($this)" w metodzie statycznej, bo nie mamy dostępu do "$this". Wspaniale. Trzeba w każdej klasie dziedziczącej nadpisywać metodę instance() powielając te linijki i zmieniając tylko to co mamy po "new", bo pomysł z ::getClassName() też nie działa.

Udało się komuś z Was zrobić klasę bazową dla singletonów coś jak ten mój "AbstractSingleton"?
Nalfein][WR
Póki co wymyśliłem protezę, podaję w razie czego:

[php:1:2d17acddaf]
class AbstractSingleton
{
function instance($class) {
static $instance;
if (!$instance) $instance = new $class;
return $instance;
}

}

class test extends AbstractSingleton
{
function instance($class = '') {
return parent::instance($class ? $class : 'test');
}
}

class test2 extends test
{
function instance($class = '') {
return parent::instance($class ? $class : 'test2');
}
}

assert(is_a(test::instance(), 'test'));
[/php:1:2d17acddaf]

Niewiele mniej pisania, ale działa dobrze.
Nalfein][WR
Proteza też okazała się spieprzona, bo get_class(test::instance()) == get_class(test2::instance()) - zmienna statyczna jest dzielona w obrębie całego drzewa klas. Inna proteza, już działająca:

[php:1:2e43b9dedd]
class AbstractSingleton
{
function instance($class) {
static $instance[$class];
if (!isset($instance[$class])) $instance[$class] = new $class;
return $instance[$class];
}

}
[/php:1:2e43b9dedd]

Działa, ale jest wolniejsza, bo przy każdym odwołaniu szuka obiektu w tablicy...
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.