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à.