[PHP] Static variabele wordt niet overschreven *

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 19:24

Patriot

Fulltime #whatpulsert

Topicstarter
Goeiemiddag,

Ik ben bezig met een scriptje, en nu loop ik tegen een probleem aan. Ik heb een abstracte klasse (we noemen hem even klasse A) waarin ik een property declareer maar nog geen waarde geef. Ik extend die klasse A met klasse B, waarin ik de variabele wel een waarde geef. Naast die property, heeft de klasse A ook nog een constructor. Deze is niet abstract, en maakt gebruik van de static property.

Een beetje pseudo-code om het te verduidelijken:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

abstract class A {
  static protected $var;

  public function __construct()
  {
    echo self::$var;
  }
} 

class B extends A {

  static protected $var = 'Hello World';

}

$b = new B();


In dit geval wil ik dat de uitkomst hiervan is: "Hello World", dit is niet het geval. Ik vermoed dat dit komt doordat er als het ware twee "versies" zijn van de property $var. Die van klasse A, en die van klasse B.

Ik vermoed dat het een mogelijkheid is om klasse B een constructor te geven, die de property van zijn parent op de goede waarde zet. Het probleem daarmee is dat er ook nog een klasse C kan zijn, die de static variabele bijvoorbeeld de waarde "Hallo Wereld" wil geven. Als dat het geval is zou de "Hello World" van klasse B worden overschreven.

Ik zoek hier een oplossing voor, die ik me zo snel niet kan bedenken. Het property moet echt static zijn, omdat ik deze in klasse B gebruik in een static function.

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Volgens mij moet je nog even wat leesvoer doorwerken :)

http://www.fluffycat.com/...OO-Abstract-Class-Basics/

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 21:31

Gonadan

Admin Beeld & Geluid, Harde Waren
beter lezen

[ Voor 70% gewijzigd door Gonadan op 06-08-2008 12:56 ]

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

Verwijderd

Ik zie niet in wat die link met het TS probleem te maken heeft. Statics vars kunnen prima overschreven worden, ze kunnen alleen niet overidden worden. Wat hier gebeurd is waarschijnlijk 'shadowing'.

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

My bad :) ik had het idee dat hij functionaliteit uit de abastract class web moest halen...

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 19:24

Patriot

Fulltime #whatpulsert

Topicstarter
Ik snap het principe van abstrace klasses, althans; ik lees niets nieuws op de door jou aangehaalde pagina. Ik weet ook wat het static keyword doet. Het probleem is dat ik nog nooit ergens iets heb gelezen over de combinatie van een static property met een abstracte klasse. Ik had verwacht dat de property overschreven zou worden door de klasse die de abstracte klasse extend. Dat is dus blijkbaar niet het geval, en dat is mijn probleem.

Ik heb een abstracte klasse waarin een aantal functies staan die voor alle child-klassen hetzelfde zijn; die zijn niet abstract en volledig uitgeschreven. Ik dacht daarbij een static variabele te kunnen gebruiken, dit werkt echter niet goed omdat de static property met dezelfde naam in de child-klasse, niet de property van de parent-klasse overschrijft.

Ik begrijp eigenlijk wel waarom dit gebeurt, maar dat helpt mij niet in het vinden van een oplossing, ik hoopte dat jullie mij daar mee konden helpen.

EDIT: Het komt in feite door het feit dat je bij het gebruiken van de Paamayim Nekudotayim specifiek aangeeft welke klasse hij moet gebruiken. In dit geval gebruik ik self, die verwijst naar klasse A. Ik wil natuurlijk dat hij in dat geval naar klasse B verwijst.

[ Voor 10% gewijzigd door Patriot op 06-08-2008 13:07 ]


Acties:
  • 0 Henk 'm!

  • Mr. Bondt
  • Registratie: Februari 2005
  • Laatst online: 27-08 14:50
Je wilt waarschijnlijk dit: http://nl2.php.net/manual....late-static-bindings.php, maar dat zit helaas pas in PHP 5.3.0. Ik zou zeggen, lees de comments op die pagina even door, misschien haal je er inspiratie uit :)

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Statische variabelen worden niet geerft, want een statische variabele is onderdeel van de class en niet van een class instantie.

Voeg eens onderstaan aan je voorbeeld toe.
PHP:
1
2
3
4
5
6
class C extends A {
  static protected $var = 'Goobye World';
}

$b = new B():
$c = new C();

Zou zou statische variabelen kunne erven, dan zou A::$var op dat moment ook voor B 'Goodbye world' zijn. Statische variabelen hebben ook niets met de class instance zelf te maken want het zijn variabele welke bestaan gedurende de levensduur van de applicatie (script in dit geval).

Een mogelijk oplossing:
Maar je kunt aan A toch gewoon functies toevoegen welke de statische waarde van A benaderd?

PHP:
1
2
3
4
5
6
7
8
9
10
abstract class A {
  static protected $var; 

  public function GetVar()
  {
     return A::$var;
  } 
}

echo(B->GetVar());

Echter alle instances van A geven dezelfde waarde terug.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 19:24

Patriot

Fulltime #whatpulsert

Topicstarter
Mr. Bondt schreef op woensdag 06 augustus 2008 @ 13:38:
Je wilt waarschijnlijk dit: http://nl2.php.net/manual....late-static-bindings.php, maar dat zit helaas pas in PHP 5.3.0. Ik zou zeggen, lees de comments op die pagina even door, misschien haal je er inspiratie uit :)
Dat is inderdaad de oplossing voor mijn probleem. Ik heb me er inmiddels bij neergelegd dat het niet handig als die property static is. Ik moet dus een andere oplossing gaan vinden voor de static functie die ik aanroep.

EDIT:
Een mogelijk oplossing:
Maar je kunt aan A toch gewoon functies toevoegen welke de statische waarde van A benaderd?

PHP:
1
2
3
4
5
6
7
8
9
10
abstract class A {
  static protected $var; 

  public function GetVar()
  {
     return A::$var;
  } 
}

echo(B->GetVar());

Echter alle instances van A geven dezelfde waarde terug.
Nee, want ik moet in A een static variabele uit B hebben. Dat zou dus worden B::$var, ware het niet dat er ook een klasse C moet zijn die weer een eigen waarde heeft. Het moet dus eigenlijk zijn: child::$var (als tegenhanger van parent).

[ Voor 34% gewijzigd door Patriot op 06-08-2008 14:01 ]


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Patriot schreef op woensdag 06 augustus 2008 @ 13:50:
[...]


Dat is inderdaad de oplossing voor mijn probleem. Ik heb me er inmiddels bij neergelegd dat het niet handig als die property static is. Ik moet dus een andere oplossing gaan vinden voor de static functie die ik aanroep.

EDIT:


[...]


Nee, want ik moet in A een static variabele uit B hebben. Dat zou dus worden B::$var, ware het niet dat er ook een klasse C moet zijn die weer een eigen waarde heeft. Het moet dus eigenlijk zijn: child::$var (als tegenhanger van parent).
Dan doe je het zo ( Ik weet niet precies de PHP syntax, maar het idee is denk wel duidelijk )

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
abstract class A { 
  static protected $var; 

  public function __construct() 
  { 
    echo GetVar(); 
  }

  public abstract function GetVar();
}  

class B extends A { 

  static protected $var = 'Hello World'; 

  public function GetVar(){
     return self::$var;
  }

} 

$b = new B();

Al weet ik niet hoe PHP ermee omgaat als je virtuele functies aanroept in de constructor. Maar het is ook een vreemd idee dat de Constructor van A afhankelijk is van zijn SubClass B

[ Voor 8% gewijzigd door Woy op 06-08-2008 14:13 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 19:24

Patriot

Fulltime #whatpulsert

Topicstarter
rwb schreef op woensdag 06 augustus 2008 @ 14:11:
[...]

Dan doe je het zo ( Ik weet niet precies de PHP syntax, maar het idee is denk wel duidelijk )

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
abstract class A { 
  static protected $var; 

  public function __construct() 
  { 
    echo GetVar(); 
  }

  public abstract function GetVar();
}  

class B extends A { 

  static protected $var = 'Hello World'; 

  public function GetVar(){
     return self::$var;
  }

} 

$b = new B();

Al weet ik niet hoe PHP ermee omgaat als je virtuele functies aanroept in de constructor. Maar het is ook een vreemd idee dat de Constructor van A afhankelijk is van zijn SubClass B
Dat is inderdaad de oplossing, het is in ieder geval netter dan simpelweg elke variabele dubbel, met één keer static.

Ik snap overigens niet wat er vreemd is aan het overschrijven van een variabele in een subklasse, die gebruikt wordt in de parent klasse. Het enige vreemde aan mijn geval is dat ik dat wilde doen met een static variabele, een stomme denkfout waarvan het achteraf heel logisch is dat het niet werkte.

[ Voor 17% gewijzigd door Patriot op 06-08-2008 14:31 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Patriot schreef op woensdag 06 augustus 2008 @ 14:24:
Ik snap overigens niet wat er vreemd is aan het overschrijven van een variabele in een subklasse, die gebruikt wordt in de parent klasse.
Dat is ook niet vreemd (al kun je redeneren dat het eigenlijk een functie moet zijn - variabelen mag iedereen namelijk aanpassen). Het is wel vreemd dat je die variabele al in de constructor van A gebruikt, omdat de constructor van B logischerwijs op dat moment nog niet is aangeroepen. In PHP gaat dit overigens wel goed, temeer ook omdat je, hoe raar ook, expliciet de base constructor aan moet gaan zitten roepen in een derived constructor 8)7

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 19:24

Patriot

Fulltime #whatpulsert

Topicstarter
.oisyn schreef op woensdag 06 augustus 2008 @ 14:35:
[...]

Dat is ook niet vreemd (al kun je redeneren dat het eigenlijk een functie moet zijn - variabelen mag iedereen namelijk aanpassen). Het is wel vreemd dat je die variabele al in de constructor van A gebruikt, omdat de constructor van B logischerwijs op dat moment nog niet is aangeroepen. In PHP gaat dit overigens wel goed, temeer ook omdat je, hoe raar ook, expliciet de base constructor aan moet gaan zitten roepen in een derived constructor 8)7
Op het moment dat ik de abstracte klasse A extend met klasse B, en ik vervolgens klasse B instantiëer, ga ik er van uit dat de constructor van A wordt uitgevoerd in de context van klasse B. Dat wil zeggen; alle properties van B zijn dan beschikbaar voor de constructor van A.

De reden dat de klasse A abstract is, is bij mij júist omdat de constructor afhankelijk is van enkele properties van de klasse die klasse A extend. In het geval van PHP is het volgens mij ook logisch om het op deze manier te doen, en daarom ook niet raar. Het is dan hoogstens raar vanuit het oogpunt van een programmeertaal waar het niet op die manier kan.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Patriot schreef op woensdag 06 augustus 2008 @ 14:45:
[...]


Op het moment dat ik de abstracte klasse A extend met klasse B, en ik vervolgens klasse B instantiëer, ga ik er van uit dat de constructor van A wordt uitgevoerd in de context van klasse B. Dat wil zeggen; alle properties van B zijn dan beschikbaar voor de constructor van A.
Die aanname zou je net zo goed andersom kunnen doen: aangezien B extend van A, wil je dat tijdens de constructor in B de staat van A al goed is, omdat je er anders niet op kunt rekenen (zoals het aanroepen van base functions e.d.). Dus in B wil je gebruik maken van de eigenschappen van A, en niet andersom.

Vrijwel alle OO programmeertalen doen het overigens op bovenstaande manier. Éérst wordt de base geconstruct, daarna pas de derived. Als je bepaalde eigenschappen bij de constructie van de base nodig hebt, kun je die ook meegeven met de ctor vanuit de ctor van B.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A
{
    protected function __construct($var)
    {
        echo $var;
    }
}

class B extends A
{
    public function __construct()
    {
        A::__construct("B");
    }
}

[ Voor 16% gewijzigd door .oisyn op 06-08-2008 15:28 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 19:24

Patriot

Fulltime #whatpulsert

Topicstarter
.oisyn schreef op woensdag 06 augustus 2008 @ 15:23:
[...]

Die aanname zou je net zo goed andersom kunnen doen: aangezien B extend van A, wil je dat tijdens de constructor in B de staat van A al goed is, omdat je er anders niet op kunt rekenen (zoals het aanroepen van base functions e.d.). Dus in B wil je gebruik maken van de eigenschappen van A, en niet andersom.

Vrijwel alle OO programmeertalen doen het overigens op bovenstaande manier. Éérst wordt de base geconstruct, daarna pas de derived. Als je bepaalde eigenschappen bij de constructie van de base nodig hebt, kun je die ook meegeven met de ctor vanuit de ctor van B.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A
{
    protected function __construct($var)
    {
        echo $var;
    }
}

class B extends A
{
    public function __construct()
    {
        A::__construct("B");
    }
}
Bij twee op zich staande klassen vind ik het eerlijk gezegd een ander verhaal. In mijn geval zijn er twee klassen die op zich nergens zijn. Hoewel de klasse B wel geinstantiëerd kán worden; zou dit in de praktijk nergens op slaan. A en B zijn beide een stukje van de puzzel, pas al ze samenkomen vormen ze een werkend geheel. Ik snap dat er niet zoveel onderscheid kan worden gemaakt van de code uit, maar dat is voor mij wel een goede verklaring voor die afhankelijkheid van A.

Wellicht strookt dit niet helemaal met het algemene gedachtengoed van programmeurs, maar ik zie niet helemaal in waarom. Ik had een aantal klassen waarin steevast dezelfde methoden terugkwamen, die waren nagenoeg identiek aan elkaar. Op deze manier heb ik dat veel minder, dus ik zie niet in hoe dit slechter zou zijn. Ook al heb ik een van subklassen afhankelijke constructor. Een abstracte klasse is toch sowieso afhankelijk van zijn subklassen?

EDIT: Dit is overigens geen kritiek hoor, ik vraag me alleen af waarom het zo gek is :P Ik ben nog niet overtuigd namelijk.

[ Voor 3% gewijzigd door Patriot op 06-08-2008 16:41 ]

Pagina: 1