PHP fóra: Builder | JakPsatWeb | Webtrh
Nejste přihlášen(a)
Mějme následující definice tříd:
abstract class A {
protected static $varX;
protected static $varY;
public function double() {
static::$varY = 2 * static::$varX;
}
public function printInfo() {
echo "X = ". static::$varX .", Y = ". static::$varY ."<br>";
}
}
class B extends A {
protected static $varX = 10;
}
class C extends A {
protected static $varX = 7;
}
Následující kód:
$b = new B;
$b->double();
$b->printInfo();
$c = new C;
$c->double();
$c->printInfo();
Potom vytiskne:
X = 10, Y = 20
X = 7, Y = 14
Pokud ale zavolám metody pro výstup v jiném pořadí, dostanu jiný výsledek.
$b = new B;
$b->double();
$c = new C;
$c->double();
$b->printInfo();
$c->printInfo();
Potom vytiskne:
X = 10, Y = 14
X = 7, Y = 14
Třídy B a C se chovají jak kdyby vůbec statickou proměnnou $varY nezdědily a tato proměnná se u třídy A (a tím pádem je společná pro B a C).
Jde to vyřešit následující úpravou (která asi zajistí, že se při volání static::$varY použijí proměnné Y v třídách B a C namísto společné A):
class B extends A {
protected static $varX = 10;
protected static $varY;
}
class C extends A {
protected static $varX = 7;
protected static $varY;
}
Můj dotaz je: Je možné to vyřešit bez toho, abych musel proměnné znovu delkarovat v B a C?
Díky za pomoc.
Pokial dobre chapem staticke premene „Staticka premena je rovnaka pre
vsetky instancie – nieje specificka pre instanciu triedy“, tak tvoj kod sa
sprava ako by sa aj mal.
V druhom pripade vytvoris instanciu triedy B kde nastavis premenu X = 10,
zavolas metodu double, ktora nastavi premenu Y.
Potom urobis instancu C kde nastavis premenu X = 7 (Premene X su prepisane –
takze niesu dedene z abstraktnej triedy), a prepise premenu Y v abstraktney
triede na 14 (Kedze staticke premene su pre triedu a nie pre instanciu).
Ak v prvom priklade pridas este jeden riadok $b->printInfo() – tak ti to vytlaci to iste.
Vyriesit sa to da jednoduchym sposobom – ze nebudes mat staticke premene.
Ak mas staticku premenu, tak ta je rovnaka pre vsetky instancie danej triedy, takze ak ju jedna instancia zmeni, tak sa zmeni pre vsetky instancie. (Toto je dobre napr na lazy initialization, singleton etc.).
Dufam ze som to trochu vysvetlil
Díky za postřeh. Mě na tomto právě připadá divné to, že se proměnná Y mění v abstraktní třídě. Třídy A a B jsou jejími potomky a proto bych očekával, že automaticky podědí statickou proměnnou. Očekával bych, že onen přidaný řádek, který mám na konci prvního příspěvku nic nezmění a že tam ten řádek díky frázi „extends A“ jako kdyby je. Ale vypadá to, že jsem asi špatně pochopil dědičnost v PHP.
Dedicnost neznamena ze sa premena skopiruje, dedicnost v tomto pripade je ako keby tam bola nejaka „shortcut“, a kedze staticke premene su na triedy nie na instancie, takze obidve tvoje triedy maju ten „shortcut“ k rovnakej premenej (v abstraktnej triede). Keby to nebola staticka premena, tak ma kazda instancia ako keby vlastnu abstraktnu triedu a nemenili by si navzajom tu premenu.
Ked prepises premenu vo svojej triede (deklarujes na novo), tak sa php uz nepozera vyssie (v abstraktnej triede) lebo uz naslo hladanu premennu/metodu.
Toto nieje len php ale vacsina objektovych jazykov.