diff --git a/language/oop5/interfaces.xml b/language/oop5/interfaces.xml
new file mode 100644
index 000000000..608589a80
--- /dev/null
+++ b/language/oop5/interfaces.xml
@@ -0,0 +1,454 @@
+
+
+
+ Interfacce degli Oggetti
+
+ Le interfacce degli oggetti permettono di creare codice che specifica quali metodi e proprietà
+ una classe deve implementare, senza dover definire come tali metodi o proprietà sono
+ implementati. Le interfacce condividono uno spazio dei nomi con le classi, i trait e le enumerazioni, quindi
+ non possono utilizzare lo stesso nome.
+
+
+ Le interfacce vengono definite allo stesso modo di una classe, ma con la parola chiave interface
+ al posto della parola chiave class e senza che alcun metodo abbia
+ il proprio contenuto definito.
+
+
+ Tutti i metodi dichiarati in un'interfaccia devono essere pubblici; questa è la natura di
+ un'interfaccia.
+
+
+ In pratica, le interfacce servono a due scopi complementari:
+
+
+
+ Permettere agli sviluppatori di creare oggetti di classi differenti che possono essere usati
+ in modo intercambiabile perché implementano la stessa interfaccia o interfacce. Un esempio comune è quello di servizi
+ multipli per l'accesso ai database, gateway multipli per i pagamenti, o differenti strategie di caching. Le
+ diverse implementazioni possono essere sostituite senza richiedere alcuna modifica al codice che le utilizza.
+
+
+ Permettere a una funzione o metodo di accettare e operare su un parametro conforme a
+ un'interfaccia, senza preoccuparsi di cos'altro l'oggetto possa fare o di come sia implementato. Queste interfacce
+ sono spesso nominate come Iterable, Cacheable, Renderable,
+ e così via per descrivere il significato del comportamento.
+
+
+
+ Le interfacce possono definire
+ metodi magici per richiedere alle classi che le implementano
+ di implementare tali metodi.
+
+
+
+ Sebbene siano supportati, includere costruttori
+ nelle interfacce è fortemente sconsigliato. Farlo riduce significativamente la flessibilità dell'oggetto che implementa
+ l'interfaccia. Inoltre, i costruttori non sono soggetti alle regole di ereditarietà, il che può causare
+ comportamenti inconsistenti e inattesi.
+
+
+
+
+ implements
+
+ Per implementare un'interfaccia, si utilizza l'operatore implements.
+ Tutti i metodi dell'interfaccia devono essere implementati all'interno della classe; non farlo
+ causerà un errore fatale. Le classi possono implementare più di un'interfaccia,
+ se desiderato, separando ciascuna interfaccia con una virgola.
+
+
+
+ Una classe che implementa un'interfaccia può utilizzare un nome diverso per i propri parametri rispetto
+ all'interfaccia. Tuttavia, a partire da PHP 8.0 il linguaggio supporta gli argomenti con nome, il che significa
+ che i chiamanti potrebbero fare affidamento sul nome del parametro nell'interfaccia. Per questa ragione, è fortemente
+ raccomandato che gli sviluppatori utilizzino gli stessi nomi di parametro dell'interfaccia che viene implementata.
+
+
+
+
+ Le interfacce possono essere estese come le classi utilizzando l'operatore extends.
+
+
+
+
+ La classe che implementa l'interfaccia deve dichiarare tutti i metodi dell'interfaccia
+ con una firma compatibile. Una classe può implementare più interfacce
+ che dichiarano un metodo con lo stesso nome. In questo caso, l'implementazione deve seguire le
+ regole di compatibilità delle firme per tutte le interfacce. Pertanto
+ è possibile applicare la covarianza e la controvarianza.
+
+
+
+
+
+ Costanti
+
+ È possibile per le interfacce avere costanti. Le costanti di interfaccia funzionano esattamente
+ come le costanti di classe.
+ Prima di PHP 8.1.0, non potevano essere sovrascritte da una classe/interfaccia che le ereditava.
+
+
+
+ Proprietà
+
+ A partire da PHP 8.4.0, le interfacce possono anche dichiarare proprietà.
+ In tal caso, la dichiarazione deve specificare se la proprietà deve essere leggibile,
+ scrivibile, o entrambi.
+ La dichiarazione dell'interfaccia si applica solo all'accesso pubblico in lettura e scrittura.
+
+
+ Una classe può soddisfare una proprietà di interfaccia in diversi modi.
+ Può definire una proprietà pubblica.
+ Può definire una
+ proprietà virtuale pubblica
+ che implementa solo l'hook corrispondente.
+ Oppure una proprietà in lettura può essere soddisfatta da una proprietà readonly.
+ Tuttavia, una proprietà di interfaccia scrivibile non può essere readonly.
+
+
+ Esempio di proprietà di interfaccia
+
+ strtoupper($this->writeable); }
+
+ // L'interfaccia richiede solo che la proprietà sia scrivibile,
+ // ma includere anche operazioni get è completamente valido.
+ // Questo esempio crea una proprietà virtuale, il che va bene.
+ public string $writeable {
+ get => $this->written;
+ set {
+ $this->written = $value;
+ }
+ }
+
+ // Questa proprietà richiede che sia la lettura che la scrittura siano possibili,
+ // quindi è necessario implementare entrambi, o permettere che abbia
+ // il comportamento predefinito.
+ public string $both {
+ get => $this->all;
+ set {
+ $this->all = strtoupper($value);
+ }
+ }
+}
+?>
+]]>
+
+
+
+
+ &reftitle.examples;
+
+ Esempio di interfaccia
+
+vars[$name] = $var;
+ }
+
+ public function getHtml($template)
+ {
+ foreach($this->vars as $name => $value) {
+ $template = str_replace('{' . $name . '}', $value, $template);
+ }
+
+ return $template;
+ }
+}
+
+// Questo non funzionerà
+// Fatal error: Class BadTemplate contains 1 abstract methods
+// and must therefore be declared abstract (Template::getHtml)
+class BadTemplate implements Template
+{
+ private $vars = [];
+
+ public function setVariable($name, $var)
+ {
+ $this->vars[$name] = $var;
+ }
+}
+?>
+]]>
+
+
+
+ Interfacce estendibili
+
+
+]]>
+
+
+
+ Compatibilità della varianza con interfacce multiple
+
+
+]]>
+
+
+
+ Ereditarietà multipla delle interfacce
+
+
+]]>
+
+
+
+ Interfacce con costanti
+
+
+]]>
+
+
+
+ Interfacce con classi astratte
+
+
+]]>
+
+
+
+ Estensione e implementazione simultanee
+
+
+]]>
+
+
+
+ Un'interfaccia, insieme alle dichiarazioni di tipo, fornisce un buon modo per assicurarsi
+ che un particolare oggetto contenga particolari metodi. Si vedano
+ l'operatore instanceof e le
+ dichiarazioni di tipo.
+
+
+
+
+
+
diff --git a/language/oop5/properties.xml b/language/oop5/properties.xml
new file mode 100644
index 000000000..f589f0df4
--- /dev/null
+++ b/language/oop5/properties.xml
@@ -0,0 +1,408 @@
+
+
+
+ Proprietà
+
+
+ Le variabili membro di una classe sono chiamate proprietà.
+ Possono essere indicate anche con altri termini come campi,
+ ma ai fini di questo riferimento verrà utilizzato il termine proprietà.
+ Sono definite utilizzando almeno un modificatore (come
+ ,
+ ,
+ oppure, a partire da PHP 8.1.0, readonly),
+ opzionalmente (tranne per le proprietà readonly), a partire da PHP 7.4,
+ seguito da una dichiarazione di tipo, seguita da una normale dichiarazione di variabile.
+ Questa dichiarazione può includere un'inizializzazione, ma questa inizializzazione
+ deve essere un valore costante.
+
+
+
+ Un modo obsoleto di dichiarare le proprietà di una classe consiste nell'utilizzare
+ la parola chiave var al posto di un modificatore.
+
+
+
+
+ Una proprietà dichiarata senza un modificatore di
+ sarà dichiarata come public.
+
+
+
+ All'interno dei metodi di una classe, le proprietà non statiche possono essere
+ accessibili utilizzando -> (Operatore Oggetto):
+ $this->property
+ (dove property è il nome della proprietà).
+ Le proprietà statiche sono accessibili utilizzando :: (Doppio due punti):
+ self::$property. Vedere
+ per ulteriori informazioni sulla differenza tra proprietà statiche e non statiche.
+
+
+ La pseudo-variabile $this è disponibile all'interno di
+ qualsiasi metodo di classe quando quel metodo è chiamato dal contesto di un oggetto.
+ $this è il valore dell'oggetto chiamante.
+
+
+
+
+ Dichiarazioni di proprietà
+
+
+]]>
+
+
+
+
+
+
+ Esistono diverse funzioni per gestire classi e oggetti.
+ Vedere il riferimento delle Funzioni Classe/Oggetto.
+
+
+
+
+ Dichiarazioni di tipo
+
+ A partire da PHP 7.4.0, le definizioni delle proprietà possono includere
+ ,
+ con l'eccezione di callable.
+
+ Esempio di proprietà tipizzate
+
+id = $id;
+ $this->name = $name;
+ }
+}
+
+$user = new User(1234, null);
+
+var_dump($user->id);
+var_dump($user->name);
+
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+ Le proprietà tipizzate devono essere inizializzate prima dell'accesso, altrimenti
+ viene lanciato un Error.
+
+ Accesso alle proprietà
+
+numberOfSides = $numberOfSides;
+ }
+
+ public function setName(string $name): void
+ {
+ $this->name = $name;
+ }
+
+ public function getNumberOfSides(): int
+ {
+ return $this->numberOfSides;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+}
+
+$triangle = new Shape();
+$triangle->setName("triangle");
+$triangle->setNumberofSides(3);
+var_dump($triangle->getName());
+var_dump($triangle->getNumberOfSides());
+
+$circle = new Shape();
+$circle->setName("circle");
+var_dump($circle->getName());
+var_dump($circle->getNumberOfSides());
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+
+ Proprietà readonly
+
+ A partire da PHP 8.1.0, una proprietà può essere dichiarata con il modificatore readonly,
+ che impedisce la modifica della proprietà dopo l'inizializzazione. Prima di PHP 8.4.0
+ una proprietà readonly è implicitamente private-set, e può essere scritta solo
+ dalla stessa classe. A partire da PHP 8.4.0, le proprietà readonly sono implicitamente
+ protected(set),
+ quindi possono essere impostate dalle classi figlie. Questo comportamento può essere sovrascritto
+ esplicitamente se desiderato.
+
+ Esempio di proprietà readonly
+
+prop = $prop;
+ }
+}
+
+$test = new Test("foobar");
+// Lettura valida.
+var_dump($test->prop); // string(6) "foobar"
+
+// Riassegnamento non valido. Non importa che il valore assegnato sia lo stesso.
+$test->prop = "foobar";
+// Error: Cannot modify readonly property Test::$prop
+?>
+]]>
+
+
+
+
+ Il modificatore readonly può essere applicato solo a proprietà tipizzate.
+ Una proprietà readonly senza vincoli di tipo può essere creata utilizzando il tipo .
+
+
+
+
+ Le proprietà statiche readonly non sono supportate.
+
+
+
+
+ Una proprietà readonly può essere inizializzata solo una volta, e solo dallo scope in cui è stata dichiarata. Qualsiasi altra assegnazione o modifica della proprietà risulterà in un'eccezione Error.
+
+ Inizializzazione non valida delle proprietà readonly
+
+prop = "foobar";
+// Error: Cannot initialize readonly property Test1::$prop from global scope
+?>
+]]>
+
+
+
+
+
+ Non è consentito specificare un valore predefinito esplicito per le proprietà readonly, poiché una proprietà readonly con un valore predefinito è essenzialmente uguale a una costante, e quindi non particolarmente utile.
+
+
+
+]]>
+
+
+
+
+
+
+ Le proprietà readonly non possono essere annullate con unset una volta inizializzate. Tuttavia, è possibile annullare una proprietà readonly prima dell'inizializzazione, dallo scope in cui la proprietà è stata dichiarata.
+
+
+
+ Le modifiche non sono necessariamente semplici assegnamenti, anche tutte le seguenti operazioni risulteranno in un'eccezione Error:
+
+
+i += 1;
+$test->i++;
+++$test->i;
+$test->ary[] = 1;
+$test->ary[0][] = 1;
+unset($test->ary[0]);
+$ref =& $test->i;
+$test->i =& $ref;
+byRef($test->i);
+foreach ($test as &$prop);
+?>
+]]>
+
+
+
+
+ Tuttavia, le proprietà readonly non impediscono la mutabilità interna. Gli oggetti (o le risorse) memorizzati nelle proprietà readonly possono comunque essere modificati internamente:
+
+
+obj->foo = 1;
+// Riassegnamento non valido.
+$test->obj = new stdClass;
+?>
+]]>
+
+
+
+
+ A partire da PHP 8.3.0, le proprietà readonly possono essere reinizializzate durante la clonazione
+ di un oggetto utilizzando il metodo __clone().
+
+ Proprietà readonly e clonazione
+
+prop = null;
+ }
+
+ public function setProp(string $prop): void {
+ $this->prop = $prop;
+ }
+}
+
+$test1 = new Test1;
+$test1->setProp('foobar');
+
+$test2 = clone $test1;
+var_dump($test2->prop); // NULL
+?>
+]]>
+
+
+
+
+
+
+ Proprietà dinamiche
+
+ Se si tenta di assegnare un valore a una proprietà inesistente su un &object;,
+ PHP creerà automaticamente una proprietà corrispondente.
+ Questa proprietà creata dinamicamente sarà disponibile solo
+ su questa istanza della classe.
+
+
+
+
+ Le proprietà dinamiche sono deprecate a partire da PHP 8.2.0.
+ Si raccomanda di dichiarare la proprietà esplicitamente.
+ Per gestire nomi di proprietà arbitrari, la classe dovrebbe implementare i metodi
+ magici __get() e
+ __set().
+ Come ultima risorsa, la classe può essere contrassegnata con l'attributo
+ #[\AllowDynamicProperties].
+
+
+
+
+
+
diff --git a/language/oop5/visibility.xml b/language/oop5/visibility.xml
new file mode 100644
index 000000000..ed3043e49
--- /dev/null
+++ b/language/oop5/visibility.xml
@@ -0,0 +1,480 @@
+
+
+
+ Visibilità
+
+ La visibilità di una proprietà, di un metodo o (a partire da PHP 7.1.0) di una costante può essere definita
+ anteponendo alla dichiarazione le parole chiave public,
+ protected o
+ private. I membri della classe dichiarati public sono
+ accessibili ovunque. I membri dichiarati protected sono accessibili
+ solo all'interno della classe stessa e dalle classi che la ereditano
+ e dalle classi genitore. I membri dichiarati come private possono essere
+ accessibili solo dalla classe che definisce il membro.
+
+
+
+ Visibilità delle proprietà
+
+ Le proprietà della classe possono essere definite come public, private o
+ protected. Le proprietà dichiarate senza alcuna parola chiave di
+ visibilità esplicita sono definite come public.
+
+
+ Dichiarazione delle proprietà
+
+public;
+ echo $this->protected;
+ echo $this->private;
+ }
+}
+
+$obj = new MyClass();
+echo $obj->public; // Funziona
+echo $obj->protected; // Errore Fatale
+echo $obj->private; // Errore Fatale
+$obj->printHello(); // Mostra Public, Protected e Private
+
+
+/**
+ * Definizione di MyClass2
+ */
+class MyClass2 extends MyClass
+{
+ // Possiamo ridichiarare le proprietà public e protected, ma non private
+ public $public = 'Public2';
+ protected $protected = 'Protected2';
+
+ function printHello()
+ {
+ echo $this->public;
+ echo $this->protected;
+ echo $this->private;
+ }
+}
+
+$obj2 = new MyClass2();
+echo $obj2->public; // Funziona
+echo $obj2->protected; // Errore Fatale
+echo $obj2->private; // Non definito
+$obj2->printHello(); // Mostra Public2, Protected2, Non definito
+
+?>
+]]>
+
+
+
+ Visibilità asimmetrica delle proprietà
+
+ A partire da PHP 8.4, le proprietà degli oggetti possono anche avere la loro
+ visibilità impostata in modo asimmetrico, con un ambito diverso per
+ la lettura (get) e la scrittura (set).
+ Nello specifico, la visibilità set può essere
+ specificata separatamente, a condizione che non sia più permissiva della
+ visibilità predefinita.
+
+
+ Visibilità asimmetrica delle proprietà
+
+author = $author; // OK
+ $this->pubYear = $year; // Errore Fatale
+ }
+}
+
+$b = new Book('How to PHP', 'Peter H. Peterson', 2024);
+
+echo $b->title; // Funziona
+echo $b->author; // Funziona
+echo $b->pubYear; // Errore Fatale
+
+$b->title = 'How not to PHP'; // Errore Fatale
+$b->author = 'Pedro H. Peterson'; // Errore Fatale
+$b->pubYear = 2023; // Errore Fatale
+?>
+]]>
+
+
+
+ A partire da PHP 8.5, la visibilità set può essere applicata anche alle proprietà statiche delle classi.
+
+
+ Visibilità asimmetrica delle proprietà statiche
+
+doAThing(); // Funziona
+echo Manager::$calls; // Funziona
+Manager::$calls = 5; // Errore fatale
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+ Ci sono alcune avvertenze riguardo alla visibilità asimmetrica:
+
+
+
+ Solo le proprietà tipizzate possono avere una visibilità set separata.
+
+
+
+
+ La visibilità set deve essere la stessa
+ di get o più restrittiva. Cioè significa che
+ public protected(set) e protected protected(set)
+ sono permessi, ma protected public(set) causerà un errore di sintassi.
+
+
+
+
+ Se una proprietà è public, allora la visibilità principale può essere
+ omessa. Cioè significa che public private(set) e private(set)
+ avranno lo stesso risultato.
+
+
+
+
+ Una proprietà con visibilità private(set)
+ è automaticamente final e non può essere ridichiarata in una classe figlia.
+
+
+
+
+ Ottenere un riferimento a una proprietà segue la visibilità set, non get.
+ Questo perché un riferimento può essere usato per modificare il valore della proprietà.
+
+
+
+
+ Analogamente, cercare di scrivere su una proprietà array implica sia un'operazione get che
+ set internamente, e pertanto seguirà la visibilità set,
+ poiché è sempre la più restrittiva.
+
+
+
+
+
+ Gli spazi non sono permessi nella dichiarazione della visibilità set.
+ private(set) è corretto.
+ private( set ) non è corretto e causerà un errore di analisi.
+
+
+
+ Quando una classe estende un'altra, la classe figlia può ridefinire
+ qualsiasi proprietà che non sia final. Nel farlo,
+ può ampliare sia la visibilità principale che la visibilità set,
+ a condizione che la nuova visibilità sia la stessa o più ampia
+ di quella della classe genitore. Tuttavia, bisogna tenere presente che se una proprietà
+ private viene sovrascritta, in realtà non cambia la proprietà del genitore
+ ma crea una nuova proprietà con un nome interno diverso.
+
+
+ Ereditarietà delle proprietà asimmetriche
+
+
+]]>
+
+
+
+
+
+
+ Visibilità dei metodi
+
+ I metodi della classe possono essere definiti come public, private o
+ protected. I metodi dichiarati senza alcuna parola chiave di
+ visibilità esplicita sono definiti come public.
+
+
+ Dichiarazione dei metodi
+
+MyPublic();
+ $this->MyProtected();
+ $this->MyPrivate();
+ }
+}
+
+$myclass = new MyClass;
+$myclass->MyPublic(); // Funziona
+$myclass->MyProtected(); // Errore Fatale
+$myclass->MyPrivate(); // Errore Fatale
+$myclass->Foo(); // Public, Protected e Private funzionano
+
+
+/**
+ * Definizione di MyClass2
+ */
+class MyClass2 extends MyClass
+{
+ // Questo è public
+ function Foo2()
+ {
+ $this->MyPublic();
+ $this->MyProtected();
+ $this->MyPrivate(); // Errore Fatale
+ }
+}
+
+$myclass2 = new MyClass2;
+$myclass2->MyPublic(); // Funziona
+$myclass2->Foo2(); // Public e Protected funzionano, Private no
+
+class Bar
+{
+ public function test() {
+ $this->testPrivate();
+ $this->testPublic();
+ }
+
+ public function testPublic() {
+ echo "Bar::testPublic\n";
+ }
+
+ private function testPrivate() {
+ echo "Bar::testPrivate\n";
+ }
+}
+
+class Foo extends Bar
+{
+ public function testPublic() {
+ echo "Foo::testPublic\n";
+ }
+
+ private function testPrivate() {
+ echo "Foo::testPrivate\n";
+ }
+}
+
+$myFoo = new Foo();
+$myFoo->test(); // Bar::testPrivate
+ // Foo::testPublic
+?>
+]]>
+
+
+
+
+
+ Visibilità delle costanti
+
+ A partire da PHP 7.1.0, le costanti di classe possono essere definite come public, private o
+ protected. Le costanti dichiarate senza alcuna parola chiave di
+ visibilità esplicita sono definite come public.
+
+
+ Dichiarazione delle costanti a partire da PHP 7.1.0
+
+foo(); // Public, Protected e Private funzionano
+
+
+/**
+ * Definizione di MyClass2
+ */
+class MyClass2 extends MyClass
+{
+ // Questo è public
+ function foo2()
+ {
+ echo self::MY_PUBLIC;
+ echo self::MY_PROTECTED;
+ echo self::MY_PRIVATE; // Errore Fatale
+ }
+}
+
+$myclass2 = new MyClass2;
+echo MyClass2::MY_PUBLIC; // Funziona
+$myclass2->foo2(); // Public e Protected funzionano, Private no
+?>
+]]>
+
+
+
+
+
+ Visibilità da altri oggetti
+
+ Gli oggetti dello stesso tipo avranno accesso ai membri private e
+ protected l'uno dell'altro anche se non sono le stesse istanze. Questo perché
+ i dettagli specifici dell'implementazione sono già noti quando ci si trova
+ all'interno di quegli oggetti.
+
+
+ Accesso ai membri private dello stesso tipo di oggetto
+
+foo = $foo;
+ }
+
+ private function bar()
+ {
+ echo 'Accessed the private method.';
+ }
+
+ public function baz(Test $other)
+ {
+ // Possiamo modificare la proprietà private:
+ $other->foo = 'hello';
+ var_dump($other->foo);
+
+ // Possiamo anche chiamare il metodo private:
+ $other->bar();
+ }
+}
+
+$test = new Test('test');
+
+$test->baz(new Test('other'));
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+