Costruttore (programmazione orientata agli oggetti) - Constructor (object-oriented programming)
Nella programmazione orientata agli oggetti basata su classi , un costruttore (abbreviazione: ctor ) è un tipo speciale di subroutine chiamato per creare un oggetto . Prepara il nuovo oggetto per l'uso, spesso accettando argomenti che il costruttore usa per impostare le variabili membro richieste .
Un costruttore assomiglia a un metodo di istanza , ma differisce da un metodo in quanto non ha un tipo restituito esplicito , non è ereditato in modo implicito e di solito ha regole diverse per i modificatori di ambito. I costruttori hanno spesso lo stesso nome della classe dichiarante . Hanno il compito di inizializzare i membri dati dell'oggetto e di stabilire l' invariante della classe , fallendo se l'invariante non è valido. Un costruttore scritto correttamente lascia l' oggetto risultante in uno stato valido . Gli oggetti immutabili devono essere inizializzati in un costruttore.
La maggior parte dei linguaggi consente di sovraccaricare il costruttore in quanto può esserci più di un costruttore per una classe, con parametri diversi. Alcuni linguaggi prendono in considerazione alcuni tipi speciali di costruttori. I costruttori, che utilizzano concretamente una singola classe per creare oggetti e restituire una nuova istanza della classe, sono astratti dalle fabbriche , che creano anch'esse oggetti ma possono farlo in vari modi, utilizzando più classi o schemi di allocazione differenti come un pool di oggetti .
tipi
Costruttori parametrizzati
I costruttori che possono accettare almeno un argomento sono definiti costruttori con parametri. Quando un oggetto viene dichiarato in un costruttore parametrizzato, i valori iniziali devono essere passati come argomenti alla funzione di costruzione. Il modo normale di dichiarazione dell'oggetto potrebbe non funzionare. I costruttori possono essere chiamati esplicitamente o implicitamente. Il metodo per chiamare implicitamente il costruttore è anche chiamato metodo abbreviato. Se vogliamo inizializzare i campi della classe con i tuoi valori, usa un costruttore parametrizzato.
class Example {
public:
Example();
Example(int a, int b); // Parameterized constructor.
private:
int x_;
int y_;
};
Example::Example() = default;
Example::Example(int x, int y) : x_(x), y_(y) {}
Example e = Example(0, 50); // Explicit call.
Example e2(0, 50); // Implicit call.
Costruttori predefiniti
Se il programmatore non fornisce un costruttore per una classe istanziabile, il compilatore Java inserisce un costruttore predefinito nel codice per conto dell'utente. Questo costruttore è noto come costruttore predefinito. Non lo troverai nel tuo codice sorgente (il file java) poiché verrebbe inserito nel codice durante la compilazione ed esiste nel file .class. Il comportamento del costruttore predefinito dipende dalla lingua. Può inizializzare i membri dati su zero o su altri stessi valori, oppure potrebbe non fare nulla. In Java, un "costruttore predefinito" si riferisce a un costruttore nullary che viene generato automaticamente dal compilatore se non sono stati definiti costruttori per la classe o in assenza di costruttori definiti dal programmatore (ad esempio in Java, il costruttore predefinito chiama implicitamente il costruttore nullary della superclasse, quindi esegue un corpo vuoto). Tutti i campi vengono lasciati al loro valore iniziale di 0 (tipi interi), 0.0 (tipi a virgola mobile), false (tipo booleano) o null (tipi di riferimento).
#include <iostream>
class Student {
public:
Student(int a = 0, int b = 0); // Default constructor.
int a;
int b;
};
Copia costruttori
Come C++, Java supporta anche "Copy Constructor". Ma, a differenza di C++, Java non crea un costruttore di copie predefinito se non ne scrivi uno tuo. I costruttori di copia definiscono le azioni eseguite dal compilatore durante la copia degli oggetti di classe. Un costruttore di copie ha un parametro formale che è il tipo della classe (il parametro può essere un riferimento a un oggetto). Viene utilizzato per creare una copia di un oggetto esistente della stessa classe. Anche se entrambe le classi sono uguali, conta come un costruttore di conversione. Sebbene i costruttori di copia siano in genere abbreviati come copy ctor o cctor, non hanno nulla a che fare con i costruttori di classi utilizzati in .NET che utilizzano la stessa abbreviazione.
Costruttori di conversione
I costruttori di conversione forniscono a un compilatore un mezzo per creare in modo implicito un oggetto appartenente a una classe in base a un oggetto di tipo diverso. Questi costruttori vengono solitamente invocati in modo implicito per convertire argomenti o operandi in un tipo appropriato, ma possono anche essere chiamati in modo esplicito.
Sposta costruttori
In C++, i costruttori di spostamento prendono un riferimento di valore a un oggetto della classe e vengono utilizzati per implementare il trasferimento di proprietà delle risorse dell'oggetto parametro.
Sintassi
- Java , C++ , C# , ActionScript , PHP 4 e MATLAB hanno una convenzione di denominazione in cui i costruttori hanno lo stesso nome della classe a cui sono associati.
- In PHP 5, un nome consigliato per un costruttore è
__construct
. Per compatibilità con le versioni precedenti, verrà chiamato un metodo con lo stesso nome della classe se__construct
non è possibile trovare il metodo. Dal PHP 5.3.3, questo funziona solo per le classi senza namespace. - In PHP 7, dovresti sempre nominare il costruttore come
__construct
. I metodi con lo stesso nome della classe attiveranno un errore di livello E_DEPRECATED. - In Perl , i costruttori sono, per convenzione, chiamati "nuovi" e devono eseguire una discreta quantità di creazione di oggetti.
- Nel sistema di oggetti Moose per Perl, i costruttori (denominati new ) vengono creati automaticamente e vengono estesi specificando un metodo BUILD .
- In Visual Basic .NET , il costruttore è chiamato "
New
". - In Python , il costruttore è suddiviso in due metodi, "
__new__
" e "__init__
". Il__new__
metodo è responsabile dell'allocazione della memoria per l'istanza e riceve la classe come argomento (chiamato convenzionalmente "cls
"). Al__init__
metodo (spesso chiamato "l'inizializzatore") viene passata l'istanza appena creata come argomento (chiamato convenzionalmente "self
"). -
I costruttori Object Pascal sono indicati dalla parola chiave "
constructor
" e possono avere nomi definiti dall'utente (ma sono principalmente chiamati "Create
"). - In Objective-C , il metodo del costruttore è suddiviso in due metodi, "
alloc
" e "init
" con ilalloc
metodo che mette da parte (allocando) la memoria per un'istanza della classe e ilinit
metodo che gestisce la maggior parte dell'inizializzazione dell'istanza. Una chiamata al metodo "new
" invoca siaalloc
ilinit
metodo che il metodo, per l'istanza della classe.
Organizzazione della memoria
In Java, C# e VB .NET, il costruttore crea oggetti di tipo riferimento in una struttura di memoria speciale chiamata " heap ". I tipi di valore (come int, double, ecc.) vengono creati in una struttura sequenziale chiamata " stack ". VB .NET e C# consentono anche l'uso dell'operatore new per creare oggetti di tipo valore, ma questi oggetti di tipo valore vengono creati nello stack indipendentemente dal fatto che l'operatore venga utilizzato o meno.
In C++, gli oggetti vengono creati nello stack quando il costruttore viene richiamato senza l'operatore new e creati nell'heap quando il costruttore viene richiamato con l'operatore new. Gli oggetti stack vengono eliminati in modo implicito quando escono dall'ambito, mentre gli oggetti heap devono essere eliminati in modo implicito da un distruttore o in modo esplicito utilizzando l' operatore di eliminazione .
Dettagli lingua
C++
In C++ , il nome del costruttore è il nome della classe. Non restituisce nulla. Può avere parametri come qualsiasi funzione membro . Le funzioni del costruttore sono solitamente dichiarate nella sezione pubblica, ma possono essere dichiarate anche nelle sezioni protette e private, se l'utente vuole limitare l'accesso ad esse.
Il costruttore ha due parti. Il primo è l' elenco degli inizializzatori che segue l' elenco dei parametri e prima del corpo del metodo. Inizia con due punti e le voci sono separate da virgole. L'elenco degli inizializzatori non è obbligatorio, ma offre l'opportunità di fornire valori per i membri dati ed evitare istruzioni di assegnazione separate. L'elenco dell'inizializzatore è obbligatorio se si dispone di membri dati di tipo const o riferimento o membri che non dispongono di logica del costruttore senza parametri. Le assegnazioni vengono eseguite in base all'ordine in cui vengono dichiarati i membri dati (anche se l'ordine nell'elenco dell'inizializzatore è diverso). La seconda parte è il corpo, che è un normale corpo del metodo racchiuso tra parentesi graffe.
C++ consente più di un costruttore. Gli altri costruttori devono avere parametri diversi. Inoltre, i costruttori che contengono parametri a cui vengono assegnati valori predefiniti, devono rispettare la restrizione secondo cui non a tutti i parametri viene assegnato un valore predefinito. Questa è una situazione che conta solo se c'è un costruttore predefinito. Il costruttore di una classe base (o classi base) può essere chiamato anche da una classe derivata. Le funzioni del costruttore non vengono ereditate e non è possibile fare riferimento ai loro indirizzi. Quando è richiesta l'allocazione della memoria, gli operatori new e delete vengono chiamati implicitamente.
Un costruttore di copie ha un parametro dello stesso tipo passato come riferimento const , ad esempio Vector(const Vector& rhs) . Se non viene fornito in modo esplicito, il compilatore usa il costruttore di copia per ogni variabile membro o semplicemente copia i valori in caso di tipi primitivi. L'implementazione predefinita non è efficiente se la classe ha membri allocati dinamicamente (o handle ad altre risorse), perché può portare a doppie chiamate all'eliminazione (o doppio rilascio di risorse) in caso di distruzione.
class Foobar {
public:
Foobar(double r = 1.0,
double alpha = 0.0) // Constructor, parameters with default values.
: x_(r * cos(alpha)) // <- Initializer list
{
y_ = r * sin(alpha); // <- Normal assignment
}
private:
double x_;
double y_;
};
Invocazioni di esempio:
Foobar a,
b(3),
c(5, M_PI/4);
Alla restituzione di oggetti dalle funzioni o al passaggio di oggetti per valore, il costruttore di copie degli oggetti verrà chiamato implicitamente, a meno che non si applichi l' ottimizzazione del valore restituito .
C++ genera implicitamente un costruttore di copia predefinito che chiamerà i costruttori di copia per tutte le classi base e tutte le variabili membro a meno che il programmatore non ne fornisca uno, elimini esplicitamente il costruttore di copia (per impedire la clonazione) o una delle classi base o variabili membro il costruttore di copia venga eliminato o non accessibile (privato). La maggior parte dei casi che richiedono un costruttore di copie personalizzato (ad es. conteggio dei riferimenti , copia profonda dei puntatori) richiedono anche la personalizzazione del distruttore e dell'operatore di assegnazione della copia . Questo è comunemente indicato come la Regola del tre .
C#
Esempio di costruttore C# :
public class MyClass
{
private int a;
private string b;
// Constructor
public MyClass() : this(42, "string")
{
}
// Overloading a constructor
public MyClass(int a, string b)
{
this.a = a;
this.b = b;
}
}
// Code somewhere
// Instantiating an object with the constructor above
MyClass c = new MyClass(42, "string");
C# costruttore statico
In C# un costruttore statico è un inizializzatore di dati statici. I costruttori statici sono anche chiamati costruttori di classi . Poiché il metodo effettivamente generato ha il nome .cctor , vengono spesso chiamati anche "cctors".
I costruttori statici consentono l'inizializzazione di variabili statiche complesse. I costruttori statici vengono chiamati implicitamente al primo accesso alla classe. Qualsiasi chiamata a una classe (chiamata statica o del costruttore), attiva l'esecuzione del costruttore statico. I costruttori statici sono thread-safe e implementano un modello singleton . Quando vengono utilizzati in una classe di programmazione generica , i costruttori statici vengono chiamati a ogni nuova istanza generica, uno per tipo. Anche le variabili statiche vengono istanziate.
public class MyClass
{
private static int _A;
// Normal constructor
static MyClass()
{
_A = 32;
}
// Standard default constructor
public MyClass()
{
}
}
// Code somewhere
// Instantiating an object with the constructor above
// right before the instantiation
// The variable static constructor is executed and _A is 32
MyClass c = new MyClass();
CFML
CFML utilizza un metodo denominato ' init
' come metodo di costruzione.
Cheese.cfc
component {
// properties
property name="cheeseName";
// constructor
function Cheese init( required string cheeseName ) {
variables.cheeseName = arguments.cheeseName;
return this;
}
}
Crea un'istanza di un formaggio.
myCheese = new Cheese( 'Cheddar' );
A partire da ColdFusion 10, CFML ha anche supportato la specifica del nome del metodo del costruttore:
component initmethod="Cheese" {
// properties
property name="cheeseName";
// constructor
function Cheese Cheese( required string cheeseName ) {
variables.cheeseName = arguments.cheeseName;
return this;
}
}
Eiffel
In Eiffel , le routine che inizializzano nuovi oggetti sono chiamate procedure di creazione . Le procedure di creazione hanno le seguenti caratteristiche:
- Le procedure di creazione non hanno un tipo di ritorno esplicito (per definizione di procedure ).
- Le procedure di creazione sono denominate.
- Le procedure di creazione sono designate per nome come procedure di creazione nel testo della classe.
- Le procedure di creazione possono essere richiamate in modo esplicito per reinizializzare gli oggetti esistenti.
- Ogni classe effettiva (cioè concreta o non astratta) deve designare almeno una procedura di creazione.
- Le procedure di creazione devono lasciare l'oggetto appena inizializzato in uno stato che soddisfi l'invariante di classe.
Sebbene la creazione di oggetti implichi alcune sottigliezze, la creazione di un attributo con una dichiarazione tipica x: T
espressa in un'istruzione di creazione create x.make
consiste nella seguente sequenza di passaggi:
- Crea una nuova istanza diretta di tipo
T
. - Eseguire la procedura di creazione sull'istanza
make
appena creata. - Associare l'oggetto appena inizializzato all'entità
x
.
Nel primo frammento di seguito, la classe POINT
è definita. La procedura make
è codificata dopo la parola chiave feature
.
La parola chiave create
introduce un elenco di procedure che possono essere utilizzate per inizializzare le istanze. In questo caso l'elenco include default_create
, una procedura con un'implementazione vuota ereditata da class ANY
e la make
procedura codificata all'interno della classe.
class
POINT
create
default_create, make
feature
make (a_x_value: REAL; a_y_value: REAL)
do
x := a_x_value
y := a_y_value
end
x: REAL
-- X coordinate
y: REAL
-- Y coordinate
...
Nel secondo frammento, una classe che è un client POINT
ha una dichiarazione my_point_1
e my_point_2
di tipo POINT
.
Nel codice procedurale, my_point_1
viene creato come origine (0.0, 0.0). Poiché non è specificata alcuna procedura di creazione, viene utilizzata la procedura default_create
ereditata dalla classe ANY
. Questa riga potrebbe essere stata codificata create my_point_1.default_create
. Solo le procedure denominate come procedure di creazione possono essere utilizzate in un'istruzione con la create
parola chiave. La prossima è un'istruzione di creazione per my_point_2
, che fornisce i valori iniziali per le my_point_2
coordinate di . La terza istruzione effettua una normale chiamata di istanza alla make
procedura per reinizializzare l'istanza a cui è associata my_point_2
con valori diversi.
my_point_1: POINT
my_point_2: POINT
...
create my_point_1
create my_point_2.make (3.0, 4.0)
my_point_2.make (5.0, 8.0)
...
F#
In F# , un costruttore può includere qualsiasi let
o do
istruzioni definite in una classe. let
le istruzioni definiscono campi privati e le do
istruzioni eseguono il codice. È possibile definire ulteriori costruttori utilizzando la new
parola chiave.
type MyClass(_a : int, _b : string) = class
// Primary constructor
let a = _a
let b = _b
do printfn "a = %i, b = %s" a b
// Additional constructors
new(_a : int) = MyClass(_a, "") then
printfn "Integer parameter given"
new(_b : string) = MyClass(0, _b) then
printfn "String parameter given"
new() = MyClass(0, "") then
printfn "No parameter given"
end
// Code somewhere
// instantiating an object with the primary constructor
let c1 = new MyClass(42, "string")
// instantiating an object with additional constructors
let c2 = new MyClass(42)
let c3 = new MyClass("string")
let c4 = MyClass() // "new" keyword is optional
Giava
In Java , i costruttori differiscono dagli altri metodi in quanto:
- I costruttori non hanno mai un tipo restituito esplicito.
- I costruttori non possono essere invocati direttamente (la parola chiave “
new
” li richiama). - I costruttori non dovrebbero avere modificatori di non accesso.
I costruttori Java eseguono le seguenti attività nel seguente ordine:
- Chiama il costruttore predefinito della superclasse se non è definito alcun costruttore.
- Inizializza le variabili membro sui valori specificati.
- Esegue il corpo del costruttore.
Java consente agli utenti di chiamare un costruttore in un altro costruttore usando la this()
parola chiave. Ma this()
deve essere la prima affermazione.
class Example
{
Example() // Non-parameterized constructor
{
this(1); // Calling of constructor
System.out.println("0-arg-cons");
}
Example(int a) // Parameterized constructor
{
System.out.println("1-arg-cons");
}
}
public static void main(String[] args)
{
Example e = new Example();
}
Java fornisce l'accesso al costruttore della superclasse tramite la super
parola chiave.
public class Example
{
// Definition of the constructor.
public Example()
{
this(1);
}
// Overloading a constructor
public Example(int input)
{
data = input; // This is an assignment
}
// Declaration of instance variable(s).
private int data;
}
// Code somewhere else
// Instantiating an object with the above constructor
Example e = new Example(42);
Un costruttore che accetta un numero zero di argomenti è chiamato costruttore "no-arguments" o "no-arg".
JavaScript
A partire da ES6, JavaScript ha costruttori diretti come molti altri linguaggi di programmazione. Sono scritti come tali
class FooBar {
constructor(baz) {
this.baz = baz
}
}
Questo può essere istanziato come tale
const foo = new FooBar('7')
L'equivalente di questo prima di ES6, era la creazione di una funzione che istanzia un oggetto in quanto tale
function FooBar (baz) {
this.baz = baz;
}
Questo viene istanziato allo stesso modo di sopra.
Oggetto Pascal
In Object Pascal , il costruttore è simile a un metodo factory . L'unica differenza sintattica rispetto ai metodi regolari è la parola chiave constructor
davanti al nome (invece di procedure
o function
). Può avere qualsiasi nome, sebbene la convenzione sia quella di avere Create
come prefisso, come in CreateWithFormatting
. La creazione di un'istanza di una classe funziona come chiamare un metodo statico di una classe: TPerson.Create('Peter')
.
program OopProgram;
type
TPerson = class
private
FName: string;
public
property Name: string read FName;
constructor Create(AName: string);
end;
constructor TPerson.Create(AName: string);
begin
FName := AName;
end;
var
Person: TPerson;
begin
Person := TPerson.Create('Peter'); // allocates an instance of TPerson and then calls TPerson.Create with the parameter AName = 'Peter'
end.
OCaml
In OCaml , c'è un costruttore. I parametri sono definiti subito dopo il nome della classe. Possono essere utilizzati per inizializzare le variabili di istanza e sono accessibili in tutta la classe. Un metodo nascosto anonimo chiamato initializer
consente di valutare un'espressione immediatamente dopo che l'oggetto è stato costruito.
class person first_name last_name =
object
val full_name = first_name ^ " " ^ last_name
initializer
print_endline("Hello there, I am " ^ full_name ^ ".")
method get_last_name = last_name
end;;
let alonzo = new person "Alonzo" "Church" in (*Hello there, I am Alonzo Church.*)
print_endline alonzo#get_last_name (*Church*)
PHP
Nella versione 5 di PHP e successive, il costruttore è un metodo denominato __construct()
(si noti che è un doppio trattino basso), che la parola chiave new
chiama automaticamente dopo aver creato l'oggetto. Di solito viene utilizzato per eseguire automaticamente inizializzazioni come le inizializzazioni di proprietà. I costruttori possono anche accettare argomenti, nel qual caso, quando new
viene scritta l' istruzione, è necessario inviare anche gli argomenti del costruttore per i parametri.
class Person
{
private string $name;
public function __construct(string $name): void
{
$this->name = $name;
}
public function getName(): string
{
return $this->name;
}
}
Perla 5
Nel linguaggio di programmazione Perl versione 5, per impostazione predefinita, i costruttori sono metodi di fabbrica , ovvero metodi che creano e restituiscono l'oggetto, nel senso concreto di creare e restituire un riferimento benedetto. Un tipico oggetto è un riferimento a un hash, sebbene raramente vengano utilizzati anche riferimenti ad altri tipi. Per convenzione l'unico costruttore è denominato new , sebbene sia consentito denominarlo diversamente o avere più costruttori. Ad esempio, una classe Person può avere un costruttore denominato new , nonché un costruttore new_from_file che legge un file per gli attributi Person e new_from_person che utilizza un altro oggetto Person come modello.
package Person;
# In Perl constructors are named 'new' by convention.
sub new {
# Class name is implicitly passed in as 0th argument.
my $class = shift;
# Default attribute values, if you have any.
my %defaults = ( foo => "bar" );
# Initialize attributes as a combination of default values and arguments passed.
my $self = { %defaults, @_ };
# Check for required arguments, class invariant, etc.
if ( not defined $self->{first_name} ) {
die "Mandatory attribute missing in Person->new(): first_name";
}
if ( not defined $self->{last_name} ) {
die "Mandatory attribute missing in Person->new(): last_name";
}
if ( defined $self->{age} and $self->{age} < 18 ) {
die "Invalid attribute value in Person->new(): age < 18";
}
# Perl makes an object belong to a class by 'bless'.
bless $self, $class;
return $self;
}
1;
Perl 5 con Moose
Con il sistema di oggetti Moose per Perl, la maggior parte di questo standard può essere omessa, viene creata una nuova impostazione predefinita , possono essere specificati gli attributi e se possono essere impostati, ripristinati o richiesti. Inoltre, qualsiasi funzionalità aggiuntiva del costruttore può essere inclusa in un metodo BUILD che il costruttore generato da Moose chiamerà, dopo aver verificato gli argomenti. È possibile specificare un metodo BUILDARGS per gestire gli argomenti del costruttore non nel formato hashref / key => valore.
package Person;
# enable Moose-style object construction
use Moose;
# first name ( a string) can only be set at construction time ('ro')
has first_name => (is => 'ro', isa => 'Str', required => 1);
# last name ( a string) can only be set at construction time ('ro')
has last_name => (is => 'ro', isa => 'Str', required => 1);
# age (Integer) can be modified after construction ('rw'), and is not required
# to be passed to be constructor. Also creates a 'has_age' method which returns
# true if age has been set
has age => (is => 'rw', isa => 'Int', predicate => 'has_age');
# Check custom requirements
sub BUILD {
my $self = shift;
if ($self->has_age && $self->age < 18) { # no under 18s
die "No under-18 Persons";
}
}
1;
In entrambi i casi la classe Person viene avviata in questo modo:
use Person;
my $p = Person->new( first_name => 'Sam', last_name => 'Ashe', age => 42 );
Pitone
In Python , i costruttori sono definiti da uno o entrambi i metodi __new__
e __init__
. Viene creata una nuova istanza chiamando la classe come se fosse una funzione, che chiama i metodi __new__
e __init__
. Se un metodo del costruttore non è definito nella classe, verrà chiamato il successivo trovato nell'ordine di risoluzione dei metodi della classe .
Nel caso tipico, __init__
è necessario definire solo il metodo. (L'eccezione più comune è per gli oggetti immutabili.)
>>> class ExampleClass:
... def __new__(cls, value):
... print("Creating new instance...")
... # Call the superclass constructor to create the instance.
... instance = super(ExampleClass, cls).__new__(cls)
... return instance
... def __init__(self, value):
... print("Initialising instance...")
... self.payload = value
>>> exampleInstance = ExampleClass(42)
Creating new instance...
Initialising instance...
>>> print(exampleInstance.payload)
42
Le classi normalmente agiscono come fabbriche per nuove istanze di se stesse, ovvero una classe è un oggetto chiamabile (come una funzione), con la chiamata che è il costruttore e la chiamata alla classe restituisce un'istanza di quella classe. Tuttavia, al __new__
metodo è consentito restituire qualcosa di diverso da un'istanza della classe per scopi specializzati. In tal caso, __init__
non viene invocato.
Raku
Con Raku , è possibile tralasciare ancora più standard, dato che viene ereditato un nuovo metodo predefinito , è possibile specificare gli attributi e se possono essere impostati, ripristinati o richiesti. Inoltre, qualsiasi funzionalità aggiuntiva del costruttore può essere inclusa in un metodo BUILD che verrà chiamato per consentire l'inizializzazione personalizzata. È possibile specificare un metodo TWEAK per post-elaborare qualsiasi attributo già (implicitamente) inizializzato.
class Person {
has Str $.first-name is required; # First name (a string) can only be set at
# construction time (the . means "public").
has Str $.last-name is required; # Last name (a string) can only be set at
# construction time (a ! would mean "private").
has Int $.age is rw; # Age (an integer) can be modified after
# construction ('rw'), and is not required
# during the object instantiation.
# Create a 'full-name' method which returns the person's full name.
# This method can be accessed outside the class.
method full-name { $!first-name.tc ~ " " ~ $!last-name.tc }
# Create a 'has-age' method which returns true if age has been set.
# This method is used only inside the class so it's declared as "private"
# by prepending its name with a !
method !has-age { self.age.defined }
# Check custom requirements
method TWEAK {
if self!has-age && $!age < 18 { # No under 18
die "No person under 18";
}
}
}
La classe Person viene istanziata in questo modo:
my $p0 = Person.new( first-name => 'Sam', last-name => 'Ashe', age => 42 );
my $p1 = Person.new( first-name => 'grace', last-name => 'hopper' );
say $p1.full-name(); # OUTPUT: «Grace Hopper»
In alternativa, i parametri nominati possono essere specificati utilizzando la sintassi della coppia di due punti in Perl 6:
my $p0 = Person.new( :first-name<Sam>, :last-name<Ashe>, :age(42) );
my $p1 = Person.new( :first-name<Grace>, :last-name<Hopper> );
E se hai impostato variabili con nomi identici ai parametri denominati, puoi utilizzare una scorciatoia che utilizzerà il nome della variabile per il parametro denominato:
my $first-name = "Sam";
my $last-name = "Ashe";
my $age = 42;
my $p0 = Person.new( :$first-name, :$last-name, :$age );
Rubino
In Ruby , i costruttori vengono creati definendo un metodo chiamato initialize
. Questo metodo viene eseguito per inizializzare ogni nuova istanza.
irb(main):001:0> class ExampleClass
irb(main):002:1> def initialize
irb(main):003:2> puts "Hello there"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> ExampleClass.new
Hello there
=> #<ExampleClass:0x007fb3f4299118>
Visual Basic .NET
In Visual Basic .NET , i costruttori utilizzano una dichiarazione di metodo con il nome " New
".
Class Foobar
Private strData As String
' Constructor
Public Sub New(ByVal someParam As String)
strData = someParam
End Sub
End Class
' code somewhere else
' instantiating an object with the above constructor
Dim foo As New Foobar(".NET")
Guarda anche
- RAII
- Sito di assegnazione
- Modello Creativo
- Distruttore
- Costruttore globale in C++ e la sua controparte C, attributo della funzione ((costruttore))