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 __constructnon è 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 il allocmetodo che mette da parte (allocando) la memoria per un'istanza della classe e il initmetodo che gestisce la maggior parte dell'inizializzazione dell'istanza. Una chiamata al metodo " new" invoca sia allocil initmetodo 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: Tespressa in un'istruzione di creazione create x.makeconsiste nella seguente sequenza di passaggi:

  • Crea una nuova istanza diretta di tipo T.
  • Eseguire la procedura di creazione sull'istanza makeappena 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 createintroduce 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 ANYe la makeprocedura 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 POINTha una dichiarazione my_point_1e my_point_2di tipo POINT.

Nel codice procedurale, my_point_1viene creato come origine (0.0, 0.0). Poiché non è specificata alcuna procedura di creazione, viene utilizzata la procedura default_createereditata 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 createparola chiave. La prossima è un'istruzione di creazione per my_point_2, che fornisce i valori iniziali per le my_point_2coordinate di . La terza istruzione effettua una normale chiamata di istanza alla makeprocedura per reinizializzare l'istanza a cui è associata my_point_2con 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 leto doistruzioni definite in una classe. letle istruzioni definiscono campi privati ​​e le doistruzioni eseguono il codice. È possibile definire ulteriori costruttori utilizzando la newparola 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:

  1. Chiama il costruttore predefinito della superclasse se non è definito alcun costruttore.
  2. Inizializza le variabili membro sui valori specificati.
  3. 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 superparola 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 constructordavanti al nome (invece di procedureo function). Può avere qualsiasi nome, sebbene la convenzione sia quella di avere Createcome 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 initializerconsente 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 newchiama 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 newviene 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

Appunti

Riferimenti