Un GM è un essere umano? Se si, puoi estendere la classe umano e farla ereditare alla classe GM: l’eredità in PHP Object Oriented Programming.

L’eredità è uno dei capisaldi della programmazione orientata agli oggetti. Ha numerosi vantaggi: scrittura di meno codice, flessibilità nella costruzione di applicazioni, risorse minimaliste e problema della ridondanza risolto. Che senso avrebbe per me creare un altra classe GM quando all’ interno della classe Umano per esempio mi ritrovo delle proprietà che sono uguali a quelle delle classe che mi appresto a creare (mi riferisco a nome e cognome per esempio, visto che sono variabili immutabili per tutti)? Perchè occupare inutilmente spazi di memoria, quando di fatto quello che mi serve già esiste e non devo necessariamente ricrearlo, a questo punto mi basterà semplicemente creare una classe derivata dipendente dalla classe madre senza dover reinventare la ruota. Per logica filosofica se tutti gli umani hanno un nome e un cognome, anche i GM avranno le stesse informazioni presenti nello stesso dna e per proprietà transitiva possiamo fare i solligsti aristotelici semplicemente estendendo la classe originaria. Ma la classe GM però ha delle prorietà che la classe madre non ha, come quella di elo, per esempio. Certo il punteggio elo come variabile appartiene esclusivamente alla classe derivata GM ma questo non è un ostacolo per la nostra programmazione. Quindi iniziamo a mettere le cose in pratica creando una classe Umano:

class Umano
{
public $nome;
public $cognome;

}

Ok e adesso come faccio a creare la classe gm come derivazione della classe madre? Usando la parola chiave extends, vediamola in azione, tenendo presente che di solito la prima lettera definita nella classe deve risultare per convenzione sempre maiuscola e che all’ interno del contenitore che ho creato definirò anche un membro che è la variabile elo:

class Gm extends Umano
{
public $elo;
}

Ok ma alla fine di tutte queste astrazioni posso tirare fuori dal cappello un esempio pratico con nomi e cognomi in stampa per esempio? Una prima cosa importante da capire nell’ ereditarietà è che le proprietà presenti nella classe umano sono rese disponibili sempre e ovunque per tutte le classi derivate. Quindi potremmo fare un esperimento. Ipotizziamo di voler stampare il nome e cognome del GM a video, posso ereditare anche dei metodi dalla classe madre? Aggiorniamo lo script sulla classe Umano e facciamolo diventare in questi termini:

class Umano
{
public $nome;
public $cognome;

function stampaNome()
{
echo “Mi chiamo $this->nome $this->cognome”;
}
}

L’utilità dell’ ereditarietà si vede proprio in pratica da questo esempio del metodo stampaNome (ricordiamo che per testare dal vivo il nostro codice si può andare direttamente su come suggerito da http://phptester.net/ comesuggerito dalla nostra ottava puntata https://umbriawaysemplifica.wordpress.com/2020/04/22/grande-maestro-iscritto-a-torneo-privo-di-euro-con-i-metodi-static-in-php-oop-puo-pagare-direttamente-in-euro/) . In sostanza la classe Gm avrà l’esclusiva come classe derivata di accedere gratuitamente (essendo stato impostato a tutto public) ai metodi della classe madre, quindi il gioco di prestigio che proponiamo è proprio questo: come è possibile che io a video riesco a stampare il nome e cognome del GM richiamando una classe che non è la sua? Bè essendo una classe derivata caratterizzata dalla parola chiave extends come chiarito precedentemente in questa nuova nona puntata, tutto diventa comodo. Proviamo a vedere l’effetto che fa impostando a video dei valori reali ricordando di inserire il tutto tra i tag <?php e finale ?>, quindi lo script completo diventerà:

class Umano
{
public $nome;
public $cognome;

function stampaNome()
{
echo “Mi chiamo $this->nome $this->cognome”;
}
}

class Gm extends Umano
{
public $elo;
}

$gm=new Gm();
$gm->nome=”Fabiano”;
$gm->cognome=”Caruana”;
$gm->elo=2820;

var_dump($gm);

echo “<br><br>”;

$gm->stampaNome();

l’effetto che fa a video ha del miracoloso:

object(Gm)#1 (3) { [“elo”]=> int(2820) [“nome”]=> string(7) “Fabiano” [“cognome”]=> string(7) “Caruana” }

Mi chiamo Fabiano Caruana

E con questo risultato finale raggiunto in questa nona puntata sulle classi non possiamo che rimanere come si dice in gergo tecnico “brasati”!

PHP e OOP: magic method __autoload, ereditarietà, pianificazione iniziale con UML.

web developer UmbriaArticoli precedenti sullo stesso tema OOP in PHP per navigare in un mare in tempesta:

  1. https://umbriawayinfo.wordpress.com/2019/04/07/programmazione-procedurale-oppure-oop-this-is-the-problem/
  2. https://umbriawaypotenzia.wordpress.com/2019/04/07/php-versione-sette-introdotte-nuove-direttive-per-trasformare-il-linguaggio-in-fortemente-tipicizzato/
  3. https://umbriawaysemplifica.wordpress.com/2019/04/08/ambito-di-visibilita-delle-variabili-in-php-public-protected-private/
  4. https://umbriawaytarget.wordpress.com/2019/04/08/php-oop-magic-method-e-costruttori/
  5. https://umbriawayvalorizza.wordpress.com/2019/04/08/warning-ambito-di-visibilita-publica-delle-classi-encapsulation-e-sicurezza-metodi-getter-e-setter/

In uno dei precedenti studi abbiamo visto che la nostra classe si era evoluta con un metodo nuovo:

/*

function __autoload($classi) {
$filename = __DIR__ . ‘/classi/’ . $classi . ‘.php’;
require_once $filename;
}

*/

Il progettista dell’ applicazione ha l’obbligo di snellire le linee di codice e nel caso di lunghi listati di aggirarare le istruzioni come require_once “classi/Libro.php”; e pertanto con la funzione precedente, definita magic method come il famoso costruttore __construct() possiamo recuperare automaticamente i nostri collegamenti alle classi diminuendo le possibilità di errore nel nostro software inserendo per l’appunto il path dove possiamo recuperare la classe specifica, per l’appunto

/*

function __autoload($classi) {
$filename = __DIR__ . ‘/classi/’ . $classi . ‘.php’;
require_once $filename;
}

*/

che serve a recuperare la definizione delle rispettive classi o gli ingredienti del nostro dolce.

A questo punto non ci resta che studiare l’ereditarietà, ossia quelle relazioni padre e figlio che riguardano le proprietà e i metodi di una classe. Ipotizziamo di avere una classe prodotto generica. A questo punto potrei estendere questa classe a un oggetto figlio creando indifferentemente l’oggetto sedia, libro o televisore, con dei metodi universali GET e SET che posso riutilizzare su oggetti simili al prodotto generico, ereditando dalla superclasse, che posso estendere aggiungendo delle sottoclassi per le gli oggetti libro, sedia o televisione. L’idea è quella di creare delle superclassi universali che estese per ereditarietà generano delle estensioni della superclasse. Tutto ciò avviene introducendo una nuova parola chiave, sempre lavorando sulla visibilità PROTECTED, EXTENDS con il nome delle classe padre che si vuole estendere, in questo caso prodotto che rimanda alla sedia o al libro alla TV. Questi oggetti figlio possono leggere i metodi protetti delle definizioni delle classi genitore. Vediamo un esempio di definizione della classe prodotto:

/*
<?php
class Prodotto {
protected $price;
protected $qta;
protected $database;
public function getPrezzo() {
return $this->price;
}
public function setPrezzo($prezzo) {
$this->price = $prezzo;
}
public function getQta() {
return $this->qta;
}
public function setQta($qta) {
$this->qta = $qta;
}
public function addQta($quantita) {
$this->qta += $quantita;
}
}

*/

Le superclassi possono anche non avere il costruttore se non c’è la necessità di inizializzare le proprietà e nel caso avessimo due costruttori il conflitto padre e figlio non prende in considerazione quello della superclasse ma quello dell’ oggetto sedia figlio della definizione della classe prodotto. Dal punto di vista didattico per capire la portata della parola chiave extends all’ inizio conviene anche angolizzare la programmazione altrui, cercando di studiare le ottimizzazioni sul codice e come le specificità dell’ oggetto singolo vengono gestite partendo dalle funzionalità già presenti nella superclasse. A questo punto la nostra classe Libro diventerà una estensione di una superclasse, facendo attenzione di incapuslare delle proprietà private con l’uso della parola chiave sulla prima riga class Libro extends Prodotto:

/*

class Libro extends Prodotto {
private $titolo;
private $autore;
private $codiceisbn;
private $prezzousato;
public function __construct($tit,$aut,$cod,$qta=1) {
$this->titolo = $tit;
$this-> autore = $aut;
$this-> codiceisbn = $cod;
$this-> qta = $qta;
}
public function getTitolo() {
return $this->titolo;
}
public function getIsbn() {
return $this->codiceisbn;
}
public function setIsbn($isbn) {
$this->codiceisbn = $isbn;
}
public function setPrezzo($prezzo) {
$this->price = $prezzo;
}
public function inPrestito($cod,$qta) {
$this->qta -= $qta;
}
}
*/

A questo punto diamo un occhiata al linguaggio UML acronimo di unified modeling language, “linguaggio di modellizzazione unificato” che utilizza una scatola analitica con tre riquadri, il nome della classe, la lista delle proprietà e quella dei metodi. Questo vale sia per le classi padri e le loro estensioni. In questa fase di pianificazione iniziale si prevedono anche i valori che devono avere le variabili e il tipo di dati da utilizzare per ciascuna. Con protected possiamo accedere anche alle definizione di classi derivate quindi è consigliabile rispetto all’ uso di private. Quindi graficamente possiamo disegnare queste scatole con tre sezioni che al loro interno conterranno tutte le particelle che utilizzeremo nel nostro software.

Blog su WordPress.com.

Su ↑