46 – 47 OOP oggetti 4 – ereditarietà 1
Creiamo una nuova classe che ci permette di definire un dado:
class Dado { private $valoreAttuale=0, $numeroFacce=6; public function __construct($numeroFacce) { if($numeroFacce>0) $this->numeroFacce=$numeroFacce;} public function lancia() { $this->valoreAttuale = rand(1, $this->numeroFacce); return $this->valoreAttuale; } public function getValore() {return $this->valoreAttuale;} }
Abbiamo 2 proprietà private (non richiamabili esternamente la classe)
$valoreAttuale=0, $numeroFacce=6;
La prima è il valore del lancio, zero stabilisce che il dado non è stato ancora lanciato. La seconda è il numero delle facce del dado, visto che è previsto avere anche un dado con meno facce di sei.
public function __construct($numeroFacce) { if($numeroFacce>0) $this->numeroFacce=$numeroFacce;}
Ho creato un costruttore pubblico che prevede il parametro numerofaccie. Quando creerò un oggetto dado dovrò specificare obbligatoriamente il parametro del costruttore che andrà a sovrascrivere il valore della proprietà $numeroFacce.
public function lancia() { $this->valoreAttuale = rand(1, $this->numeroFacce); return $this->valoreAttuale; }
Un metodo pubblico lancia che simulerà, se richiamata, l’azione del lancio del dado sovrascrivendo il valore di $valoreAttuale, con uno generato casualmente (funzione rand) compreso tra 1 ed il numero di facce scelto durante la futura creazione dell’oggetto dado. Il numero generato verrà restituito (return)
public function getValore() {return $this->valoreAttuale;}
Se richiamato, questo metodo restituisce il valore che il dado ha in quel momento.
Inserisco anche la nostra classe di servizio io per la formattazione.
class io { const NL="<br />"; static public function linea($carattere, $quanti) { return str_repeat($carattere, $quanti);} static public function saltaRighe($quanti) { echo str_repeat(self::NL, $quanti); } }
Creo l’oggetto unDado:
$unDado = new Dado(3); for($lanci=1;$lanci<100;$lanci++) echo $unDado->lancia().io::NL;
Un dado con sole 3 facce e un ciclo che simula 100 lanci richiamando il metodo lancia creato nella classe. Ecco il codice completo:
<?php class io { const NL="<br />"; static public function linea($carattere, $quanti) { return str_repeat($carattere, $quanti);} static public function saltaRighe($quanti) { echo str_repeat(self::NL, $quanti); } } class Dado { private $valoreAttuale=0, $numeroFacce=6; public function __construct($numeroFacce) { if($numeroFacce>0) $this->numeroFacce=$numeroFacce;} public function lancia() { $this->valoreAttuale = rand(1, $this->numeroFacce); return $this->valoreAttuale; } public function getValore() {return $this->valoreAttuale;} } $unDado = new Dado(3); for($lanci=1;$lanci<100;$lanci++) echo $unDado->lancia().io::NL; ?>
Ora vogliamo truccare il dado in modo che mi genererà più volte un numero che scegliamo.
Iniziamo con aggiungere 2 proprietà alla classe dado: $facciaTruccata e $quantoTruccata
private $valoreAttuale=0, $numeroFacce=6, $facciaTruccata=0, $quantoTruccata=0 ;
La proprietà $facciaTruccata stabilisce il numero che voglio esca maggiormente. La proprietà $quantoTruccata,invece, permette di stabilire la quantità di probabilità che il numero scelto esca maggiormente (stabilendo che il numero da far uscire di più sia 4 e metto $quantitaTrucco=10 il numero casuale non sarà più compreso tra 1 e 6, ma tra 1 e 16 con una probabilità che esca il 4 di 11 volte su 16). Per far ciò aggiungiamo un setter con 2 argomenti alla classe dado:
public function setFacciaTruccata_Trucco($faccia, $trucco) {if ($faccia>0 && $faccia<$this->numeroFacce && $trucco>0) $this->facciaTruccata = $faccia; $this->quantoTruccata = $trucco;}
Questo doppio setter dice: scegli il numero da truccare ($faccia) e quanto vuoi che esca ($trucco), se il numero della faccia e maggiore di zero e però non è maggiore del numero delle facce del dado, giusto da avere un controllo (&& $faccia<$this->numeroFacce) e il grado di trucco è maggiore anch’esso di zero, altrimenti non serve a niente, allora metti i 2 valori scelti rispettivamente nelle proprietà $facciaTruccata e $quantoTruccata.
$unDado->setFacciaTruccata_Trucco(4,5);
all’oggetto unDado aggiungiamo 4, che è il numero che voglio esca di più e 5 che la quantità di frequenza di uscita di quel numero (il numero casuale sarà generato tra 1 e 11 dato da 6 $numeroFacce + 5 $quantoTruccata). Bisogna però modificare il metodo lancia della classe dado:
public function lancia() { $this->valoreAttuale = rand(1, $this->numeroFacce + $this-> quantoTruccata); if ($this->facciaTruccata>0 && $this->valoreAttuale>$this-> numeroFacce) $this->valoreAttuale = $this->facciaTruccata; return $this->valoreAttuale; }
L’ estrazione rand sarà sempre compreso tra 1 e numerofacce incrementato della quantità del trucco ($this->numeroFacce + $this->quantoTruccata). Poi dico se mi trovo in modalità truccata ($this->facciaTruccata>0) ed è uscito un numero maggiore delle facce per esempio 8 (&& $this->valoreAttuale>$this->numeroFacce) trasforma valoreAttuale per esempio 8 in facciaTruccata nel ns esempio 4. Ecco tutta la classe dado completa:
class Dado { private $valoreAttuale=0, $numeroFacce=6, $facciaTruccata=0, $quantoTruccata=0 ; public function __construct($numeroFacce) { if($numeroFacce>0) $this->numeroFacce=$numeroFacce;} public function setFacciaTruccata_Trucco($faccia, $trucco) {if ($faccia>0 && $faccia<$this->numeroFacce && $trucco>0) $this->facciaTruccata = $faccia; $this->quantoTruccata = $trucco;} public function lancia() { $this->valoreAttuale = rand(1, $this->numeroFacce + $this->quantoTruccata); if ($this->facciaTruccata>0 && $this->valoreAttuale>$this->numeroFacce) $this->valoreAttuale = $this->facciaTruccata; return $this->valoreAttuale; } public function getValore() {return $this->valoreAttuale;} }
Come si può notare la classe Dado è particolarmente macchinosa e poco fluida a colpo d’occhio, per cui, nella prossima lezione, spezziamo la classe in 2 (sotto) classi separate più semplici, una che descrive il dado e l’altra il trucco. Questo esercizio introdurrà il concetto di ereditarietà.