Protected
L'indicatore di visibilità protected
è più restrittivo rispetto al precedente: le proprietà ed i metodi non sono accessibili e modificabili dall'esterno della classe ma lo sono dalle classi che ereditano:
class MyClass {
// proprietà
protected $a = 10;
// metodi
protected function sayHello() {
echo "Hello!";
}
}
class AnotherClass extends MyClass {
public function sayHelloAgain() {
$this->sayHello();
}
}
$anotherClass = new AnotherClass();
// stampa "Hello!"
$anotherClass->sayHelloAgain();
Se si tenta di accedere o modificare una proprietà protected
o di chiamare un metodo protected
dall'esterno della classe:
// errore
echo $myClass->a;
// errore
$myClass->sayHello();
il tutto risulterebbe in un Fatal Error:
Fatal error: Cannot access protected property AnotherClass::$a in [...] on line 116
Fatal error: Call to protected method MyClass::sayHello() from context '' in [...] on line 116
Private
L'indicatore di visibilità private
è il più restrittivo dei tre. Le proprietà dichiarate come private sono accessibili/modificabili solo dall'interno della classe che li dichiara, cosi come i metodi privati sono richiamabili solo al suo interno:
class MyClass {
// proprietà
private $a = 10;
// metodi
private function sayHello() {
echo "Hello!";
}
public function getAll() {
echo $this->a;
$this->sayHello();
}
}
class AnotherClass extends MyClass {
public function sayHelloAgain() {
$this->sayHello();
}
}
$anotherClass = new AnotherClass();
// stampa "10 Hello!"
$anotherClass->getAll();
In questo caso l'unico modo che abbiamo per accedere al valore della proprietà a è tramite un metodo pubblico (se vogliamo accedervi dall'esterno) oppure tramite un metodo protetto (se vogliamo accedervi solo dalle classi che ereditano). Nel nostro esempio abbiamo optato per il metodo pubblico getAll
, che oltre a riuscire ad accedere al valore della proprietà a, richiama il metodo privato sayHello
.
Se invece, tentassimo di richiamare il metodo sayHello
dall'esterno della classe o dall'interno delle sottoclassi, anche in questo caso otterremmo un Fatal Error:
$anotherClass->sayHello();
Fatal error: Call to private method MyClass::sayHello() from context 'AnotherClass' in [...] on line 149
La stessa cosa accarebbe ovviamente se richiamassimo il metodo sayHelloAgain
della classe AnotherClass, dato che quest'ultimo richiama erroneamente un metodo privato:
$anotherClass->sayHelloAgain();
Fatal error: Call to private method MyClass::sayHello() from context 'AnotherClass' in [...] on line 149
Conclusione
L'introduzione degli indicatori di visibilità permette al modello OOP di PHP di avvicinarsi sempre di più al modello originale. Tramite gli indicatori di visibilità possiamo introdurre nuove regole all'interno delle nostre applicazioni, rendendole più robuste e maggiormente mantenibili. Inoltre, la presenza degli indicatori di visibilità porta un altro, grandissimo vantaggio: la possibilità di mettere in pratica i Design Patterns. Alcuni di questi "modelli" infatti (dalla quale prendono vita gli ormai indispensabili Web Services), possono essere realizzati unicamente tramite i differenti indicatori di visibilità, come ad esempio il pattern Singleton che nella maggioranza dei casi richiede un costruttore privato.