50 OOP oggetti 5 – ereditarietà 3

Creo una classe madre figure dove inserisco delle proprietà comuni

class figure
{
 private
 $colore = 0x000000,
 $tipoLinea = "solida",
 $spessoreLinea = 1;
}

ora creo 2 classi figlie che restituiscono il valore dell’area

class rettangolo extends figure
{
 public function area()
 {
 return 100;
 }
}

class cerchio extends figure
{
 public function area()
 {
 return 200;
 }
}

Creo gli oggetti e stampo i valori delle aree

$elencoFigure = array();
$elencoFigure[0] = new rettangolo();
$elencoFigure[1] = new cerchio();
for($i=0; $i<count($elencoFigure); $i++)
 echo $elencoFigure[$i]->area() . io::NL;

la prima cosa da notare è che è possibile creare array con insiemi di oggetti che non sono dello stesso tipo, memorizzandoli nello stesso contenitore ($elencoFigure). Ho messo nella prima posizione [0] un rettangolo e nella seconda [1] un cerchio. Poi il ciclo for richiede il metodo area per ciascuna figura.

Potrebbe accadere che nelle classi che si vanno a creare, qualcuno si dimenticasse di includere un metodo area per una figura, quindi il progettista della classe figure vuole assicurarsi che ciò non accada. Specificare un metodo area nella classe madre, avrebbe poco senso, perché il calcolo dell’area varia da figura a figura e la formula sarebbe diversa e sarebbe impossibile calcolare l’area di una figura che ancora non conosciamo. La soluzione è creare un metodo astratto con la keyword abstract, inserendolo anche nella dichiarazione della classe:

abstract class figure
{
 private
 $colore = 0x000000,
 $tipoLinea = "solida",
 $spessoreLinea = 1;
 
 abstract public function area();
}

Chiunque accederà al codice, si accorgerà fin da subito che all’interno della classe figure troverà dei metodi astratti che obbligatoriamente dovrà definire e qualora il metodo astratto area() non venga definito nelle classi figlie, php restituirà un errore. In questo modo gli eventuali errori di dimenticanza nelle classi figlie saranno eliminati.

Una classe astratta è instanziabile, ovvero non si possono creare oggetti con tale classe

 $unaFigura = new figure();

Tale creazione di oggetto genererà errore, perché la classe astratta può essere usata solo come modello per i suoi discendenti.

Non è possibile aggiungere nuovi parametri nel metodo figlio che richiama quello astratto madre

abstract public function area(); //astratto madre senza parametri

public function area($num) // metodo figlio scorretto

il parametro $num non esiste nella funzione astratta madre e non può essere aggiunto a meno che non gli si assegna un valore definito


abstract public function area(); //astratto madre senza parametri

public function area($num="cmq") // metodo accettato

inoltre nella classe figlia non è possibile restringere il tipo di metodo rispetto a quella madre. Se il tipo di quella madre è public il metodo figlio deve essere per forza public. Se fosse protected, nel metodo figlio sarebbe o protected o ampliarle a public (non private). Se fosse private potrebbe diventare private o protected o public.