class met array van subclass
zoals hier
Code (php)
Hoe kan ik echter adres forceren als type cAdres?
Hoe kan ik een array van type Bool of int forceren?
Jan
Gewijzigd op 26/12/2020 19:36:58 door Jan R
Code (php)
Ik ben alleen niet zo gecharmeerd van lege strings '' als geldige waarde voor vereiste data. Maak die liever nullable als ze mogen ontbreken.
Voor een parameter die null mag zijn zet je een vraagteken voor het datatype:
Code (php)
Gewijzigd op 26/12/2020 20:40:09 door Ward van der Put
Wat met array of type? (2° vraag)
Jan
Jan R op 27/12/2020 18:26:46:
Wat met array of type? (2° vraag)
Als een array een vaste structuur heeft, dan zou ik er een value object van maken of, afhankelijk van het gewenste gedrag. bijvoorbeeld een stack, heap of queue.
Voor spelers heb ik al een subclasse. ik wil dus in mijn bestaande classe een array invoeren van classe spelers.
voorbeeld
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
class clsxmt{
public float $version=3.2;
public int $AantalSpelers;
public string $Name;
public array $Speler;
public array $MarkedGames;
}
class CMarkedGame {
public int $x;
public int $y;
public int $color;
}
class cSpeler{
public string $Name='';
public clsAdvantage $Advantage;
public string $StamNummer='';
public string $Elo='';
public string $Remarq='';
public $Punten = array();
public $Remarqs = array();
public function __construct(){
$this->Advantage = new clsAdvantage;
}
public int $UniekNR;
}
class clsAdvantage{
public float $Punten=0;
public float $WeerstandsPunten=0;
public float $WinstPunten=0;
}
?>
class clsxmt{
public float $version=3.2;
public int $AantalSpelers;
public string $Name;
public array $Speler;
public array $MarkedGames;
}
class CMarkedGame {
public int $x;
public int $y;
public int $color;
}
class cSpeler{
public string $Name='';
public clsAdvantage $Advantage;
public string $StamNummer='';
public string $Elo='';
public string $Remarq='';
public $Punten = array();
public $Remarqs = array();
public function __construct(){
$this->Advantage = new clsAdvantage;
}
public int $UniekNR;
}
class clsAdvantage{
public float $Punten=0;
public float $WeerstandsPunten=0;
public float $WinstPunten=0;
}
?>
Speler = array van type cSpeler
MarkedGames = array van CMarkedGame
Punten = array van string lengte 1
Remarqs = array van string lengte onbekend
Jan
Wil je een array een striktere vorm geven, dan doe je dat niet in de array zelf, maar in de methode die de array opbouwt of vult. Daartoe kun je een klasse definiëren die zich als een array gedraagt door ArrayObject te extenden of ArrayAccess te implementeren.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
class Child
{
protected $name; /* string */
function getName() {
return $this->name;
}
function setName($name) {
$this->name = $name;
return $this;
}
}
class Master
{
protected $children; /* array */
public function addChild(Child $child) {
$this->children[] = $child;
return $this;
}
public function getChildren() {
return $this->children;
}
}
$master = new Master();
$child = new Child();
$child->setName('Jan');
$master->addChild($child);
$child = new Child();
$child->setName('Miep');
$master->addChild($child);
foreach($master->getChildren() as $child)
{
echo $child->getName() . "\n";
}
?>
class Child
{
protected $name; /* string */
function getName() {
return $this->name;
}
function setName($name) {
$this->name = $name;
return $this;
}
}
class Master
{
protected $children; /* array */
public function addChild(Child $child) {
$this->children[] = $child;
return $this;
}
public function getChildren() {
return $this->children;
}
}
$master = new Master();
$child = new Child();
$child->setName('Jan');
$master->addChild($child);
$child = new Child();
$child->setName('Miep');
$master->addChild($child);
foreach($master->getChildren() as $child)
{
echo $child->getName() . "\n";
}
?>
Toevoeging op 04/01/2021 09:30:38:
p.s. Waar het pas interessant gaat worden is als je een functie removeChild() wilt toevoegen.
$children is in bovengenoemd voorbeeld een numerieke array. Je kan dan removeChild($key) doen maar dat is helemaal niet gebruiksvriendelijk. Als je immers de key van de array niet weet moet je dat als "gebruiker" van de class zelf gaan uitvogelen. In C++ kun je operators van de class overschrijven zodat je invloed kunt uitoefenen op het vergelijken van objecten of kopiëren van objecten. Dat kan in php helaas niet. Wel kun je aan de Child class een vergelijk functie toevoegen:
Code (php)
Bovenstaande zou je nog beter doen door een abstracte class te schrijven met een naam als Comparable maar dat gaat misschien op dit moment wat ver..
Realiseer je ook dat je voor een goede vergelijking een unieke identifier nodig hebt. Het voorbeeld van mij voorziet hier niet in want als twee Children dezelfde $name hebben dan gaat het mis. Een unique identifier (of unique id) kan ook uit meerdere properties van de class bestaan.
Gewijzigd op 04/01/2021 09:47:03 door Frank Nietbelangrijk
Als je met zo'n externe identifier via de interne structuur van parent directe toegang nodig hebt tot één individueel child, deugt je ontwerp waarschijnlijk niet. Vermoedelijk heb je dan functionaliteit met een eigen verantwoordelijkheid die je moet afsplitsen naar een aparte class; de parent is dan meer een container die je als traversable met een foreach doorloopt.
Waar ik aan dacht is:
Code (php)
De verantwoordelijkheid of twee Childs hetzelfde zijn of niet ligt bij de Child class. Er is ook een manier zonder compare functie middels Reflection maar dat is omslachtig en heeft ook nadelen.
Opbouwende kritiek is welkom Ward :-)
Gewijzigd op 04/01/2021 13:51:21 door Frank Nietbelangrijk
Bij een numerieke array zou ik in plaats van een interne oplopende integer de globaal unieke spl_object_id() gebruiken:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
class MasterClass
{
private array $children = [];
public function addChild(Child $child): void
{
$this->children[spl_object_id($child)] = $child;
}
public function removeChild(Child $child): bool
{
$key = spl_object_id($child);
if (array_key_exists($key, $this->children)) {
unset($this->children[$key]);
return true;
}
return false;
}
}
?>
class MasterClass
{
private array $children = [];
public function addChild(Child $child): void
{
$this->children[spl_object_id($child)] = $child;
}
public function removeChild(Child $child): bool
{
$key = spl_object_id($child);
if (array_key_exists($key, $this->children)) {
unset($this->children[$key]);
return true;
}
return false;
}
}
?>
Bestaat het gevaar dat je array letterlijk of figuurlijk een dubbele Jan Jansen bevat, voor vader en zoon bijvoorbeeld? Dan heb je dat probleem ook al buiten de array en vervolgens bij het opbouwen van de array voor de class: het is daarom geen probleem dat je in/met de class moet oplossen, want dan ben je te laat.
Thanks Ward. Ja zo kan het ook al zou ik meestal voor het unique id uit de database kiezen welke je in 99% van de gevallen ook binnen handbereik hebt.