Tipo di oggetto (programmazione orientata agli oggetti) - Object type (object-oriented programming)

In informatica , un tipo di oggetto (noto anche come oggetto wrapping ) è un tipo di dati utilizzato nella programmazione orientata agli oggetti per avvolgere un tipo non oggetto per farlo sembrare un oggetto dinamico .

Alcuni linguaggi di programmazione orientati agli oggetti fanno una distinzione tra riferimenti e tipi di valore , spesso indicati come oggetti e non oggetti su piattaforme in cui non esistono tipi di valore complessi, per ragioni quali efficienza di runtime e problemi di sintassi o semantica. Ad esempio, Java ha classi wrapper primitive corrispondenti a ciascun tipo primitivo : Integere int, Charactere char, Floate float, ecc. Linguaggi come il C++ hanno poca o nessuna nozione di tipo di riferimento ; quindi, l'uso del tipo di oggetto è di scarso interesse.

Boxe

Il boxing, altrimenti noto come wrapping, è il processo di posizionamento di un tipo primitivo all'interno di un oggetto in modo che il primitivo possa essere utilizzato come oggetto di riferimento. Ad esempio, in Java, a LinkedListpuò cambiare la sua dimensione, ma un array deve avere una dimensione fissa. Si potrebbe desiderare di avere a LinkedListof int, ma la LinkedListclasse elenca solo i riferimenti a oggetti dinamici: non può elencare i tipi primitivi, che sono tipi di valore.

Per aggirare ciò, intpossono essere inseriti in un box Integer, che sono oggetti dinamici, e quindi aggiunti a un LinkedListdi Integer. (Utilizzando tipi parametrici generici introdotti in J2SE 5.0, questo tipo è rappresentato come .) D'altra parte, C# non ha classi wrapper primitive, ma consente il boxing di qualsiasi tipo di valore, restituendo un riferimento generico . In Objective-C , qualsiasi valore primitivo può essere preceduto da a per ricavarne un valore (ad esempio o ). Ciò consente di aggiungerli in una qualsiasi delle raccolte standard, ad esempio un file . LinkedList<Integer>Object@NSNumber@123@(123)NSArray

L'oggetto boxed è sempre una copia dell'oggetto valore, ed è solitamente immutabile . L'unboxing dell'oggetto restituisce anche una copia del valore memorizzato. Il boxing e l'unboxing ripetuti di oggetti possono avere un grave impatto sulle prestazioni, perché il boxing alloca dinamicamente nuovi oggetti e l'unboxing (se il valore boxed non viene più utilizzato) li rende idonei per la garbage collection . Tuttavia, i Garbage Collector moderni come il Garbage Collector predefinito Java HotSpot possono raccogliere in modo più efficiente oggetti di breve durata, quindi se gli oggetti in scatola sono di breve durata, l'impatto sulle prestazioni potrebbe non essere così negativo.

In alcuni linguaggi esiste un'equivalenza diretta tra un tipo primitivo unboxed e un riferimento a un tipo di oggetto boxed immutabile. Infatti, è possibile sostituire tutti i tipi primitivi in ​​un programma con tipi di oggetto boxed. Mentre l'assegnazione da una primitiva all'altra ne copierà il valore, l'assegnazione da un riferimento a un oggetto in un riquadro a un altro copierà il valore del riferimento per fare riferimento allo stesso oggetto del primo riferimento. Tuttavia, ciò non causerà alcun problema, perché gli oggetti sono immutabili, quindi non c'è semanticamente alcuna differenza reale tra due riferimenti allo stesso oggetto oa oggetti diversi (a meno che non si guardi all'uguaglianza fisica). Per tutte le operazioni diverse dall'assegnazione, come l'aritmetica, il confronto e gli operatori logici, è possibile decomprimere il tipo boxed, eseguire l'operazione e ricomporre il risultato secondo necessità. Pertanto, è possibile non memorizzare affatto i tipi primitivi.

Autoboxing

Autoboxing è il termine per ottenere un tipo di riferimento da un tipo di valore solo attraverso la conversione del tipo (implicita o esplicita). Il compilatore fornisce automaticamente il codice sorgente aggiuntivo che crea l'oggetto.

Ad esempio, nelle versioni di Java precedenti a J2SE 5.0, il codice seguente non veniva compilato:

Integer i = new Integer(9);
Integer i = 9; // error in versions prior to 5.0!

I compilatori precedenti alla 5.0 non accetterebbero l'ultima riga. Integersono oggetti di riferimento, sulla superficie non diversi da List, Object, e così via. Per convertire da an inta Integer, si doveva creare un'istanza "manualmente" dell'oggetto Integer. A partire da J2SE 5.0, il compilatore accetterà l'ultima riga e la trasformerà automaticamente in modo che venga creato un oggetto Integer per memorizzare il valore 9. Ciò significa che, da J2SE 5.0 in poi, qualcosa come , where e are , verrà compilato ora: a e b vengono unboxed, i valori interi vengono sommati e il risultato viene autoboxato in un nuovo , che viene infine memorizzato all'interno di variabile . Gli operatori di uguaglianza non possono essere utilizzati in questo modo, perché gli operatori di uguaglianza sono già definiti per i tipi di riferimento, per l'uguaglianza dei riferimenti; per verificare l'uguaglianza del valore in un tipo boxed, è comunque necessario decomprimerli manualmente e confrontare le primitive, oppure utilizzare il metodo. Integer c = a + babIntegerIntegercObjects.equals

Un altro esempio: J2SE 5.0 consente al programmatore di trattare una raccolta (come un LinkedList) come se contenesse intvalori anziché Integeroggetti. Ciò non contraddice quanto detto sopra: la raccolta contiene ancora solo riferimenti a oggetti dinamici e non può elencare tipi primitivi. Non può essere un , ma deve essere un invece. Tuttavia, il compilatore trasforma automaticamente il codice in modo che l'elenco riceva oggetti "silenziosi", mentre il codice sorgente menziona solo valori primitivi. Ad esempio, il programmatore ora può scrivere e pensare come se fossero aggiunti alla lista; ma il compilatore avrà effettivamente trasformato la riga in . LinkedList<int>LinkedList<Integer>list.add(3)int 3list.add(new Integer(3))

Spacchettamento

L'unboxing si riferisce all'ottenimento del valore associato a un determinato oggetto, solo tramite la conversione del tipo (implicita o esplicita). Il compilatore fornisce automaticamente il codice sorgente aggiuntivo che recupera il valore da quell'oggetto, invocando un metodo su quell'oggetto o con altri mezzi.

Ad esempio, nelle versioni di Java precedenti a J2SE 5.0, il codice seguente non veniva compilato:

Integer k = new Integer(4);
int l = k.intValue(); // always okay
int m = k;            // would have been an error, but okay now

C# non supporta l'unboxing automatico nello stesso significato di Java, perché non ha un set separato di tipi primitivi e tipi di oggetti. Tutti i tipi che hanno sia la versione primitiva che quella oggetto in Java, vengono implementati automaticamente dal compilatore C# come tipi primitivi (valore) o tipi oggetto (riferimento).

In entrambe le lingue, il boxing automatico non viene downcast automaticamente, ovvero il codice seguente non verrà compilato:

C#:

int i = 42;
object o = i;         // box
int j = o;            // unbox (error)
Console.WriteLine(j); // unreachable line, author might have expected output "42"

Giava:

int i = 42;
Object o = i;          // box
int j = o;             // unbox (error)
System.out.println(j); // unreachable line, author might have expected output "42"

Digita aiutanti

Modern Object Pascal ha un altro modo per eseguire operazioni su tipi semplici, simili al boxing, chiamati type helper in FreePascal o record helper in Delphi e FreePascal in modalità Delphi.
I dialetti menzionati sono linguaggi da compilazione a nativi Object Pascal e quindi mancano alcune delle funzionalità che C# e Java possono implementare. In particolare l' inferenza del tipo in fase di esecuzione su variabili fortemente tipizzate.
Ma la caratteristica è legata alla boxe.
Consente al programmatore di utilizzare costrutti come

{$ifdef fpc}{$mode delphi}{$endif}
uses sysutils;  // this unit contains wraps for the simple types
var
  x:integer=100;
  s:string;
begin
  s:= x.ToString;
  writeln(s);
end.

Riferimenti