|
Home -> Manuali e Tutorials -> Guida PHP -> Classi (2/3)
Scarica il tutorial | Stampa il tutorial | Cerca nel sito
CLASSI PHP
extends
Spesso si ha bisogno di avere classi con variabili e funzioni simili ad altre classi. É buona norma definire una classe in modo generico, sia per poterla riutilizzare spesso, sia per poterla adattare a scopi specifici. Per facilitare questa operazione, è possibile generare classi per estensione di altre classi. Una classe estesa o derivata ha tutte le variabili e le funzioni della classe di base (questo fenomeno è chiamato 'eredità') più tutto ciò che viene aggiunto dall'estensione.
Non è possibile che una sottoclasse, ridefinisca variabili e funzioni di una classe madre.
Una classe estesa dipende sempre da una singola classe di base: l'eredità multipla non è supportata. Le classi si estendono usando la parola chiave 'extends'.
<?php
class Named_Cart extends Cart2
{
var $owner;
function set_owner ($name)
{
$this->owner = $name;
}
}
$ncart = new Named_Cart; // Crea un carrello con nome
$ncart->set_owner("kris"); // Assegna il nome al carrello
print $ncart->owner; // stampa il nome del proprietario
$ncart->add_item("10", 1); // (funzionalità ereditata da Cart)
?>
|
Qui viene definita una classe Named_Cart che ha tutte le funzioni e variabili di Cart2 più la variabile $owner e la funzione set_owner(). Viene creato un carrello con nome con il metodo usato in precedenza, in più la classe estesa permette di settare o leggere il nome del carrello.
La relazione mostrata è chiamata relazione "genitore-figlio". Si crea una classe di base, poi utilizzando extends si crea una nuova classe basata sulla classe genitore: la classe figlia. Successivamente si può usare la classe figlia come classe base per un'altra classe.
A volte è utile riferirsi alle funzioni ed alle variabili di classi base o riferirsi alle funzioni di classi senza istanziarle. L'operatore :: è usato per questi scopi.
<?php
class A
{
function example()
{
echo "Sono la funzione originale A::example()";
}
}
class B extends A
{
function example()
{
echo "Sono la funzione ridefinita B::example()";
A::example();
}
}
// non viene istanziato nessun oggetto dalla classe A.
// ma il codice stampa
// Sono la funzione originale A::example()
A::example();
// crea un oggetto dalla classe B.
$b = new B;
// questo codice stampa
// Sono la funzione ridefinita B::example()
// Sono la funzione originale A::example()
$b->example();
?>
|
L'esempio chiama la funzione example() della classe A, ma senza creare un'istanza di A, di modo che la funzione non si possa richiamare con $a->example(). example() è chiamata come 'funzione della classe', e non come funzione di un oggetto della classe. Si possono usare funzioni della classe, ma non le variabili della classe. Infatti, non esiste nessun oggetto nel momento della chiamata della funzione. Quindi, la funzione della classe non può usare le variabili dell'oggetto (ma può usare le variabili locali e globali) e $this non può essere usato. Nel suddetto esempio, la classe B ridefinisce la funzione example(). La funzione originale definita nella classe A è adombrata e non più disponibile, a meno che voi non chiamiate esplicitamente con l'operatore ::, scrivendo A::example() per richiamare la funzione.
E' possibile ritrovarsi a scrivere classi con codice che si riferisce a variabili e funzioni di classi base. Ciò è particolarmente VERO se una classe derivata è un perfezionamento o una specializzazione di una classe base. Invece di usare il nome letterale della classe, bisognerebbe usare il nome speciale parent, che si riferisce al nome della classe base definita nella dichiarazione di extends. Usando questo metodo, si evita di usare il nome della classe base nel codice scritto. Se l'albero di eredità cambiasse durante lo sviluppo della classe, il cambiamento si ridurrebbe semplicemente alla modifica della dichiarazione extends della classe.
<?php
class A
{
function example()
{
echo "Sono la funzione originale A::example()";
}
}
class B extends A
{
function example()
{
echo "Sono B::example() e fornisco una funzionalità aggiuntiva.";
parent::example();
}
}
$b = new B;
// Il codice chiama B::example(), che a sua volta chiama A::example().
$b->example();
?>
|
Visibilità
La visibiltà di una property o di un metodo, può essere definita prefissando la loro dichiarazione con una parola chiave: "public", "protected" o "private". Public dichiara un metodo o una variabile che può essere vista da tutti, Protected invece limita l'accesso alla classe che la definisce ed alle sue sottoclassi, mentre Private consente l'accesso alla sola classe che la definisce.
Esempio:
<?php
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // Funziona
echo $obj->protected; // va in Errore
echo $obj->private; // va in Errore
$obj->printHello(); // Mostra Public, Protected e Private
class MyClass2 extends MyClass
{
// Si può ridichiarare i metodi public protected, ma non quello privato
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj->public; // Funziona
echo $obj2->private; // Indefinita
echo $obj2->protected; // va in Errore
$obj2->printHello(); // Mostra Public, Protected2, e non Private
?>
|
Nell'esempio seguente, invece, viene mostrato lo stesso concetto di visibilità applicato però ai metodi di una classe:
<?php
class MyClass
{
// il Costruttore deve essere public
public function __construct() { }
// dichiarazione di un metodo public
public function MyPublic() { }
// dichiarazione di un metodo protected
protected function MyProtected() { }
// dichiarazione di un metodo private
private function MyPrivate() { }
// questo è public
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); // Funziona
$myclass->MyProtected(); // va in Errore
$myclass->MyPrivate(); // va in Errore
$myclass->Foo(); // Public, Protected e Private funzionano
class MyClass2 extends MyClass
{
// questo è public
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // va in Errore
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Funziona
$myclass2->Foo2(); // Public e Protected funzionano, ma non Private
?>
|
Torna su | Indice Guida | Pagina << 18 >>
|