diff --git a/language/oop5/anonymous.xml b/language/oop5/anonymous.xml new file mode 100644 index 000000000..380c37392 --- /dev/null +++ b/language/oop5/anonymous.xml @@ -0,0 +1,223 @@ + + + + Classi anonime + + + Le classi anonime sono utili quando è necessario creare oggetti semplici e utilizzati una sola volta. + + + + +setLogger(new Logger()); + +// Utilizzo di una classe anonima +$util->setLogger(new class { + public function log($msg) + { + echo $msg; + } +}); +]]> + + + + + Possono passare argomenti ai loro costruttori, estendere altre classi, + implementare interfacce e usare trait proprio come una classe normale: + + + + +num = $num; + } + + use SomeTrait; +}); +]]> + + &example.outputs; + + + int(10) +} +]]> + + + + + Annidare una classe anonima all'interno di un'altra classe non le dà accesso + ai metodi o alle proprietà private o protette di quella classe esterna. Per + utilizzare le proprietà o i metodi protetti della classe esterna, la classe anonima + può estendere la classe esterna. Per utilizzare le proprietà private della + classe esterna nella classe anonima, devono essere passate attraverso il suo + costruttore: + + + + +prop) extends Outer { + private $prop3; + + public function __construct($prop) + { + $this->prop3 = $prop; + } + + public function func3() + { + return $this->prop2 + $this->prop3 + $this->func1(); + } + }; + } +} + +echo (new Outer)->func2()->func3(); +]]> + + &example.outputs; + + + + + + + Tutti gli oggetti creati dalla stessa dichiarazione di classe anonima sono istanze + di quella stessa classe. + + + + + + + &example.outputs; + + + + + + + + Le classi anonime ricevono un nome assegnato dal motore, come + dimostrato nell'esempio seguente. Questo nome deve essere considerato un + dettaglio implementativo, su cui non si dovrebbe fare affidamento. + + + + + + &example.outputs.similar; + + + + + + + + Classi anonime readonly + + A partire da PHP 8.3.0, il modificatore readonly può + essere applicato alle classi anonime. + + + Definizione di una classe anonima readonly + + prefix . ' ' . $msg; + } +}); +]]> + + + + + diff --git a/language/oop5/decon.xml b/language/oop5/decon.xml new file mode 100644 index 000000000..08920a3c2 --- /dev/null +++ b/language/oop5/decon.xml @@ -0,0 +1,405 @@ + + + + Costruttori e Distruttori + + + Costruttore + + void__construct + mixedvalues"" + + + PHP consente agli sviluppatori di dichiarare metodi costruttore per le classi. + Le classi che hanno un metodo costruttore chiamano questo metodo su ogni + oggetto appena creato, rendendolo adatto a qualsiasi inizializzazione di cui + l'oggetto potrebbe aver bisogno prima di essere utilizzato. + + + + I costruttori genitori non vengono chiamati implicitamente se la classe figlia definisce + un costruttore. Per eseguire un costruttore genitore, è necessaria una chiamata a + parent::__construct all'interno del costruttore figlio. + Se il figlio non definisce un costruttore, può essere ereditato + dalla classe genitore come un normale metodo di classe (se non è stato dichiarato + come private). + + + + Costruttori nell'ereditarietà + + +]]> + + + + A differenza degli altri metodi, __construct() + è esente dalle normali + regole di compatibilità delle firme + quando viene esteso. + + + I costruttori sono metodi ordinari che vengono chiamati durante l'istanziazione del + loro oggetto corrispondente. Come tali, possono definire un numero arbitrario di argomenti, che + possono essere obbligatori, possono avere un tipo e possono avere un valore predefinito. Gli argomenti del costruttore + vengono chiamati inserendo gli argomenti tra parentesi dopo il nome della classe. + + + Utilizzo degli argomenti del costruttore + +x = $x; + $this->y = $y; + } +} + +// Passa entrambi i parametri. +$p1 = new Point(4, 5); +// Passa solo il parametro obbligatorio. $y prenderà il valore predefinito 0. +$p2 = new Point(4); +// Con parametri nominati (a partire da PHP 8.0): +$p3 = new Point(y: 5, x: 4); +?> +]]> + + + + Se una classe non ha costruttore, o il costruttore non ha argomenti obbligatori, le parentesi + possono essere omesse. + + + Costruttori vecchio stile + + Prima di PHP 8.0.0, le classi nello spazio dei nomi globale interpretavano un metodo con lo stesso + nome della classe come costruttore vecchio stile. Quella sintassi è deprecata + e genererà un errore E_DEPRECATED ma chiamerà comunque quella funzione come costruttore. + Se sia __construct() che un metodo con lo stesso nome sono + definiti, verrà chiamato __construct(). + + + Nelle classi con namespace, o in qualsiasi classe a partire da PHP 8.0.0, un metodo con lo + stesso nome della classe non ha mai alcun significato speciale. + + Utilizzare sempre __construct() nel nuovo codice. + + + + Promozione dei parametri del costruttore + + A partire da PHP 8.0.0, i parametri del costruttore possono anche essere promossi per corrispondere a + una proprietà dell'oggetto. È molto comune che i parametri del costruttore vengano assegnati a + una proprietà nel costruttore senza essere altrimenti utilizzati. La promozione del costruttore + fornisce una scorciatoia per questo caso d'uso. L'esempio precedente può essere riscritto come segue. + + + Utilizzo della promozione delle proprietà del costruttore + + + + + + Quando un argomento del costruttore include un modificatore, PHP lo interpreterà sia come + una proprietà dell'oggetto che come un argomento del costruttore, e assegnerà il valore dell'argomento + alla proprietà. Il corpo del costruttore può quindi essere vuoto o può contenere altre istruzioni. + Eventuali istruzioni aggiuntive verranno eseguite dopo che i valori degli argomenti saranno stati assegnati + alle proprietà corrispondenti. + + + Non tutti gli argomenti devono essere promossi. È possibile mescolare argomenti promossi e non promossi, + in qualsiasi ordine. Gli argomenti promossi non hanno alcun impatto sul codice che chiama il costruttore. + + + + L'uso di un modificatore di visibilità (public, + protected o private) è il modo più comune per applicare la promozione + delle proprietà, ma qualsiasi altro singolo modificatore (come readonly) avrà lo stesso effetto. + + + + + Le proprietà degli oggetti non possono essere tipizzate come callable a causa di un'ambiguità del motore. + Di conseguenza, anche gli argomenti promossi non possono essere tipizzati come callable. Qualsiasi + altra dichiarazione di tipo è invece consentita. + + + + + Poiché le proprietà promosse vengono tradotte sia in una proprietà che in un parametro di funzione, qualsiasi + e tutte le restrizioni di denominazione per entrambe le proprietà e i parametri si applicano. + + + + + Gli attributi posti su un + argomento del costruttore promosso verranno replicati sia sulla proprietà + che sull'argomento. I valori predefiniti su un argomento del costruttore promosso verranno replicati solo sull'argomento e non sulla proprietà. + + + + + + New negli inizializzatori + + A partire da PHP 8.1.0, gli oggetti possono essere utilizzati come valori predefiniti dei parametri, + variabili statiche e costanti globali, così come negli argomenti degli attributi. + Gli oggetti possono anche essere passati a define. + + + + L'uso di un nome di classe dinamico o non stringa o di una classe anonima non è consentito. + L'uso dell'unpacking degli argomenti non è consentito. + L'uso di espressioni non supportate come argomenti non è consentito. + + + + Utilizzo di new negli inizializzatori + + +]]> + + + + + + Metodi di creazione statici + + PHP supporta un solo costruttore per classe. In alcuni casi, tuttavia, può essere + desiderabile consentire la costruzione di un oggetto in modi diversi con input diversi. + Il modo raccomandato per farlo è utilizzare metodi statici come wrapper del costruttore. + + + Utilizzo di metodi di creazione statici + +1005Elephpant"; + +class Product { + + private ?int $id; + private ?string $name; + + private function __construct(?int $id = null, ?string $name = null) { + $this->id = $id; + $this->name = $name; + } + + public static function fromBasicData(int $id, string $name): static { + $new = new static($id, $name); + return $new; + } + + public static function fromJson(string $json): static { + $data = json_decode($json, true); + return new static($data['id'], $data['name']); + } + + public static function fromXml(string $xml): static { + $data = simplexml_load_string($xml); + $new = new static(); + $new->id = (int) $data->id; + $new->name = $data->name; + return $new; + } +} + +$p1 = Product::fromBasicData(5, 'Widget'); +$p2 = Product::fromJson($some_json_string); +$p3 = Product::fromXml($some_xml_string); + +var_dump($p1, $p2, $p3); +]]> + + + + Il costruttore può essere reso private o protected per impedirne la chiamata dall'esterno. + In tal caso, solo un metodo statico sarà in grado di istanziare la classe. Poiché si trovano nella + stessa definizione di classe, hanno accesso ai metodi privati, anche se non della stessa istanza + dell'oggetto. Il costruttore privato è opzionale e può o meno avere senso a seconda del + caso d'uso. + + + I tre metodi statici pubblici dimostrano poi diversi modi di istanziare l'oggetto. + + + fromBasicData() accetta i parametri esatti necessari, quindi crea + l'oggetto chiamando il costruttore e restituendo il risultato. + fromJson() accetta una stringa JSON e la pre-elabora + per convertirla nel formato desiderato dal costruttore. Quindi restituisce il nuovo oggetto. + fromXml() accetta una stringa XML, la pre-elabora, e quindi crea un + oggetto vuoto. Il costruttore viene comunque chiamato, ma poiché tutti i parametri sono opzionali il metodo + li salta. Quindi assegna i valori alle proprietà dell'oggetto direttamente prima di restituire il risultato. + + + In tutti e tre i casi, la parola chiave static viene tradotta nel nome della classe in cui si trova il codice. + In questo caso, Product. + + + + + Distruttore + + void__destruct + + + + PHP possiede un concetto di distruttore simile a quello di altri + linguaggi orientati agli oggetti, come il C++. Il metodo distruttore verrà + chiamato non appena non ci saranno più altri riferimenti a un particolare oggetto, + o in qualsiasi ordine durante la sequenza di spegnimento. + + + Esempio di distruttore + + + + + + Come i costruttori, i distruttori genitori non verranno chiamati implicitamente dal + motore. Per eseguire un distruttore genitore, è necessario + chiamare esplicitamente parent::__destruct nel corpo del distruttore. + Inoltre, come i costruttori, una classe figlia può ereditare il distruttore del genitore + se non ne implementa uno proprio. + + + Il distruttore verrà chiamato anche se l'esecuzione dello script viene interrotta usando + exit. Chiamare exit in un distruttore + impedirà l'esecuzione delle restanti routine di spegnimento. + + + Se un distruttore crea nuovi riferimenti al suo oggetto, non verrà chiamato + una seconda volta quando il contatore dei riferimenti raggiunge nuovamente zero o durante la + sequenza di spegnimento. + + + A partire da PHP 8.4.0, quando + la raccolta dei cicli + avviene durante l'esecuzione di una + Fiber, i distruttori degli oggetti + programmati per la raccolta vengono eseguiti in una Fiber separata, chiamata + gc_destructor_fiber. + Se questa Fiber viene sospesa, ne verrà creata una nuova per eseguire eventuali + distruttori rimanenti. + La precedente gc_destructor_fiber non sarà più + referenziata dal garbage collector e potrà essere raccolta se non è + referenziata altrove. + Gli oggetti il cui distruttore è sospeso non verranno raccolti fino a quando il + distruttore non restituisce o la Fiber stessa non viene raccolta. + + + + I distruttori chiamati durante lo spegnimento dello script hanno gli header HTTP già + inviati. La directory di lavoro nella fase di spegnimento dello script può essere diversa + con alcuni SAPI (ad es. Apache). + + + + + Tentare di lanciare un'eccezione da un distruttore (chiamato durante la fase di + terminazione dello script) causa un errore fatale. + + + + + + diff --git a/language/oop5/inheritance.xml b/language/oop5/inheritance.xml new file mode 100644 index 000000000..e2c0aa530 --- /dev/null +++ b/language/oop5/inheritance.xml @@ -0,0 +1,205 @@ + + + + Ereditarietà degli oggetti + + L'ereditarietà è un principio di programmazione ben consolidato, e PHP fa uso + di questo principio nel suo modello a oggetti. Questo principio influenza il modo + in cui molte classi e oggetti si relazionano tra loro. + + + Ad esempio, quando si estende una classe, la sottoclasse eredita tutti i metodi, + le proprietà e le costanti pubbliche e protette dalla classe genitore. + A meno che una classe non sovrascriva + quei metodi, essi manterranno la loro funzionalità originale. + + + Questo è utile per definire e astrarre funzionalità, e permette + l'implementazione di funzionalità aggiuntive in oggetti simili senza la + necessità di reimplementare tutte le funzionalità condivise. + + + I metodi privati di una classe genitore non sono accessibili a una classe figlia. Di conseguenza, + le classi figlie possono reimplementare un metodo privato senza riguardo per le normali + regole di ereditarietà. Prima di PHP 8.0.0, tuttavia, le restrizioni final e static + venivano applicate ai metodi privati. A partire da PHP 8.0.0, l'unica restrizione sui metodi privati + applicata è private final per i costruttori, poiché questo + è un modo comune per "disabilitare" il costruttore quando si usano metodi factory statici. + + + La visibilità + dei metodi, delle proprietà e delle costanti può essere rilassata, ad es. un + metodo protected può essere marcato come + public, ma non possono essere ristrette, ad es. + marcare una proprietà public come private. + Un'eccezione sono i costruttori, la cui visibilità può essere ristretta, ad es. + un costruttore public può essere marcato come private + in una classe figlia. + + + + + A meno che non si usi l'autoloading, le classi devono essere definite prima di essere + utilizzate. Se una classe estende un'altra, allora la classe genitore deve essere dichiarata + prima della struttura della classe figlia. Questa regola si applica alle classi che ereditano + da altre classi e interfacce. + + + + + Non è consentito sovrascrivere una proprietà in lettura-scrittura con una proprietà readonly o viceversa. + + + readonly + public readonly int $prop; +} +?> +]]> + + + + + + + Esempio di ereditarietà + +printItem('baz'); // Output: 'Foo: baz' +$foo->printPHP(); // Output: 'PHP is great' +$bar->printItem('baz'); // Output: 'Bar: baz' +$bar->printPHP(); // Output: 'PHP is great' + +?> +]]> + + + + + Compatibilità del tipo di ritorno con le classi interne + + + Prima di PHP 8.1, la maggior parte delle classi o dei metodi interni non dichiarava i loro tipi di ritorno, + e qualsiasi tipo di ritorno era consentito quando li si estendeva. + + + + A partire da PHP 8.1.0, la maggior parte dei metodi interni ha iniziato a dichiarare "tentativamente" il loro tipo di ritorno, + in tal caso il tipo di ritorno dei metodi deve essere compatibile con il genitore esteso; + altrimenti, viene emesso un avviso di deprecazione. + L'assenza di una dichiarazione di ritorno esplicita è anch'essa considerata una mancata corrispondenza della firma, + e genera quindi l'avviso di deprecazione. + + + + Se il tipo di ritorno non può essere dichiarato per un metodo che sovrascrive a causa di problemi di compatibilità tra versioni di PHP, + è possibile aggiungere un attributo ReturnTypeWillChange per silenziare l'avviso di deprecazione. + + + + Il metodo che sovrascrive non dichiara alcun tipo di ritorno + + +]]> + + + + + Il metodo che sovrascrive dichiara un tipo di ritorno errato + + +]]> + + + + + Il metodo che sovrascrive dichiara un tipo di ritorno errato senza avviso di deprecazione + + +]]> + + + + + + + + diff --git a/language/oop5/static.xml b/language/oop5/static.xml new file mode 100644 index 000000000..3aa59b7e5 --- /dev/null +++ b/language/oop5/static.xml @@ -0,0 +1,157 @@ + + + + Parola chiave Static + + + + Questa pagina descrive l'uso della parola chiave static per + definire metodi e proprietà statiche. static può anche + essere usata per + definire variabili statiche, + definire funzioni anonime statiche + e per il + late static binding. + Consultare quelle pagine per informazioni su quei significati di + static. + + + + + Dichiarare proprietà o metodi di classe come statici li rende accessibili + senza necessità di un'istanziazione della classe. + È possibile accedervi anche staticamente all'interno di un oggetto di classe istanziato. + + + + Metodi statici + + + Poiché i metodi statici sono richiamabili senza che sia stata creata un'istanza + dell'oggetto, la pseudo-variabile $this non è + disponibile all'interno dei metodi dichiarati come statici. + + + + + Chiamare metodi non statici in modo statico genera un Error. + + + Prima di PHP 8.0.0, chiamare metodi non statici in modo statico era deprecato e + generava un avviso E_DEPRECATED. + + + + + Esempio di metodo statico + + +]]> + + + + + + Proprietà statiche + + + Le proprietà statiche sono accessibili usando + l'Operatore di Risoluzione dello Scope + (::) e non possono essere accedute tramite l'operatore oggetto + (->). + + + + È possibile referenziare la classe usando una variabile. + Il valore della variabile non può essere una parola chiave (ad es. self, + parent e static). + + + + Esempio di proprietà statica + +staticValue() . "\n"; +print $foo->my_static . "\n"; // "Proprietà" my_static non definita + +print $foo::$my_static . "\n"; +$classname = 'Foo'; +print $classname::$my_static . "\n"; + +print Bar::$my_static . "\n"; +$bar = new Bar(); +print $bar->fooStatic() . "\n"; +?> +]]> + + &example.outputs.8.similar; + + + + + + +