protected
La parola chiave "protected" in PHP dichiara un membro di classe come protetto, accessibile solo dalla classe stessa e dalle sue sottoclassi.
La parola chiave protected di PHP
protected è uno dei tre modificatori di accesso di PHP (insieme a public e private). Controlla la visibilità — chi è autorizzato a leggere o chiamare un membro di classe.
Un membro dichiarato protected può essere acceduto:
- all'interno della classe che lo dichiara, e
- all'interno di qualsiasi classe che eredita da essa (una sottoclasse).
Non può essere acceduto dall'esterno — cioè, da codice normale che semplicemente utilizza un oggetto ($obj->member). Questa via di mezzo è esattamente ciò che rende protected utile: nasconde i dettagli di implementazione al mondo esterno, permettendo comunque alle sottoclassi di costruire su di essi. Per il confronto completo, consulta Modificatori di accesso PHP.
Questa pagina tratta la sintassi, il comportamento di protected attraverso l'ereditarietà, i problemi comuni e quando usarlo al posto di private o public.
Sintassi
Inserisci la parola chiave protected davanti alla dichiarazione di una proprietà o di un metodo:
class MyClass {
protected $myProtectedProperty;
protected function myProtectedMethod() {
// Code here
}
}È anche possibile contrassegnare un membro statico come protected:
class Config {
protected static $instances = 0;
protected static function register() {
self::$instances++;
}
}protected vs private vs public
I tre modificatori differiscono solo per dove un membro è visibile:
| Modificatore | Stessa classe | Sottoclasse | Codice esterno |
|---|---|---|---|
public | sì | sì | sì |
protected | sì | sì | no |
private | sì | no | no |
La distinzione chiave: i membri private sono invisibili anche alle sottoclassi, mentre i membri protected vengono condivisi lungo la catena di ereditarietà. Scegli protected quando una sottoclasse ha legittimamente bisogno dei dati o dell'helper, ma vuoi comunque tenerli fuori dall'API pubblica.
Esempi
Gli esempi seguenti mostrano i membri protected utilizzati da una sottoclasse (consentito) — poi vedremo cosa succede quando il codice esterno tenta la stessa cosa.
<?php
// Example 1
class Animal
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
protected function getName()
{
return $this->name;
}
}
class Dog extends Animal
{
public function bark()
{
$name = $this->getName();
echo "$name barks!" . PHP_EOL;
}
}
$dog = new Dog("Rufus");
$dog->bark(); // Output: Rufus barks!
// Example 2
class BankAccount
{
protected $balance = 0;
public function deposit($amount)
{
$this->balance += $amount;
}
protected function canWithdraw($amount)
{
return $amount <= $this->balance;
}
}
class SavingsAccount extends BankAccount
{
public function withdraw($amount)
{
if ($this->canWithdraw($amount)) {
$this->balance -= $amount;
echo "Withdrawal successful!" . PHP_EOL;
} else {
echo "Insufficient funds!" . PHP_EOL;
}
}
}
$savingsAccount = new SavingsAccount();
$savingsAccount->deposit(100);
$savingsAccount->withdraw(50); // Output: Withdrawal successful!
$savingsAccount->withdraw(100); // Output: Insufficient funds!In entrambe le classi, la sottoclasse (Dog, SavingsAccount) chiama liberamente il membro protected del suo genitore. I dati e la logica degli helper rimangono riutilizzabili attraverso l'ereditarietà senza mai essere esposti al codice esterno.
L'accesso ai membri protected dall'esterno fallisce
Nel momento in cui si tenta di accedere a un membro protected dal codice normale, PHP genera un errore fatale:
<?php
class Animal {
protected $name = "Rufus";
}
$animal = new Animal();
echo $animal->name; // Fatal error: Cannot access protected property Animal::$nameQuesta è la protezione in azione — la proprietà semplicemente non fa parte della superficie pubblica dell'oggetto.
Attenzione: una sottoclasse può accedere ai membri di oggetti dello stesso tipo
Una sorpresa comune è che la visibilità viene controllata per classe, non per singolo oggetto. Un oggetto può accedere ai membri protected di un altro oggetto, purché entrambi siano istanze della stessa classe (o di una classe correlata che può vedere il membro):
<?php
class Wallet {
protected $balance = 100;
public function isRicherThan(Wallet $other): bool
{
// $other->balance is protected, but we're inside Wallet, so it's allowed
return $this->balance > $other->balance;
}
}
$a = new Wallet();
$b = new Wallet();
var_dump($a->isRicherThan($b)); // bool(false)Quando usare protected
Usa protected quando:
- Una sottoclasse ha bisogno di riutilizzare o sovrascrivere lo stato interno o i metodi helper, ma il codice esterno non deve accedervi.
- Stai progettando una classe base destinata a essere estesa (vedi Classi astratte PHP), e vuoi offrire metodi "building block" solo alle sottoclassi.
Preferisci private quando anche le sottoclassi non devono dipendere da un dettaglio interno — questo ti dà la libertà di modificarlo in seguito senza rompere le classi figlie. Preferisci public solo per l'API intenzionale e documentata della classe.
Riepilogo
- I membri
protectedsono visibili all'interno della classe dichiarante e delle sue sottoclassi, ma non al codice esterno. - È la via di mezzo tra
public(visibile ovunque) eprivate(visibile solo nella classe dichiarante). - La visibilità è applicata per classe, quindi oggetti dello stesso tipo possono vedere i membri protected l'uno dell'altro.
- Usalo per condividere gli elementi interni riutilizzabili lungo una catena di ereditarietà, tenendoli fuori dall'API pubblica.
Per approfondire, continua con Ereditarietà PHP, Classi e oggetti PHP e Proprietà statiche.