Os construtores e destrutores são metódos mágicos que executam determinadas tarefas assim que a classe é instânciada e antes de ser removida da memória.
Os construtores são especificados por um metódo chamado __construct e são executados sempre que a classe é chamada. Você pode por exemplo, atribuir valores não-primitivos a atributos da classe antes de executar qualquer ação, o que não seria possível sem um construtor.
Vamos imaginar a classe Player, que contem os atributos base de um personagem de um
jogo: username, password, money. Quando criamos um novo objeto de uma classe e você tem um
construtor, ele é tido como uma "função" que recebe os parâmetros. Olhe a classe abaixo:
// Player.php
class Player
{
public string $username; // propriedade/atributo
private string $password; // propriedade/atributo
protected float $money; // propriedade/atributo
/**
* Método mágico: construtor
*/
public function __construct(string $username, string $password, float $money)
{
$this->username = $username; // Setter do Construtor
$this->password = password_hash($password, PASSWORD_ARGON2I); // Setter do Construtor
$this->money = $money; // Setter do Construtor
}
}Note que o construtor é uma função que recebe parâmetros na ordem que você quiser. E quando vamos
instância-lá, usamos a palavra reservada new e o nome da classe Player e os parametros
('danielhe4rt','secret123', 1000) na ordem que foram declaradas no escopo do construtor e atribuimos
a uma variavel. Fica assim:
$danielhe4rt = new Player('danielhe4rt', 'secret123', 1000);Se você não passar algum dos parâmetros ou colocá-los fora de ordem, seu código apontará um erro falando que falta argumentos ou que os dados passados não seguem os mesmos tipos (lembre-se de tipar os parametros de suas funções).
Caso você queira deixar um argumento opcional, você deverá atribuir um valor padrão pra eles. Se liga:
// Player.php
class Player
{
public string $username; // propriedade/atributo
private string $password; // propriedade/atributo
protected float $money; // propriedade/atributo
/**
* Método mágico: construtor
*/
public function __construct(string $username, string $password, float $money = 1500.0)
{
$this->username = $username; // Setter do Construtor
$this->password = password_hash($password, PASSWORD_ARGON2I); // Setter do Construtor
$this->money = $money; // Setter do Construtor
}
}// Instancia sem o valor do atributo money
$danielhe4rt = new Player('danielhe4rt', 'secret123');Ele não foi necessário porquê falamos em nosso construtor que:
- Se não for passado o valor do atributo money, coloque-o como 1500.0 (valor padrão).
- Se for passado o valor do atributo money, sobrescreva o valor padrão de 1500.0 pelo valor passado na variavel.
Uma coisa bem importante sobre os atributos padrões em construtores é que eles devem ser declarados da direita para a esquerda. Entenda o caso abaixo:
// Player.php
class Player
{
public string $username; // propriedade/atributo
private string $password; // propriedade/atributo
protected float $money; // propriedade/atributo
/**
* Método mágico: construtor
*/
public function __construct(string $username = 'danielhe4rt', string $password, float $money = 1500.0)
{
$this->username = $username; // Setter do Construtor
$this->password = password_hash($password, PASSWORD_ARGON2I); // Setter do Construtor
$this->money = $money; // Setter do Construtor
}
}// Instancia sem o valor do atributo username
$danielhe4rt = new Player('secret123', 99999);Esse código acima geraria um erro assim que a classe for lida pois se há mais de 1 argumento e o primeiro dos argumentos tiver um valor padrão e o segundo não, ele não saberá como interpretar já que a declaração começa da esquerda para a direita.
Como poderiamos fazer esse cenário dar certo? Colocando os valores padrões a direita do escopo do construtor e os que não tiverem valores padrões à esquerda.
// Player.php
class Player
{
public string $username; // propriedade/atributo
private string $password; // propriedade/atributo
protected float $money; // propriedade/atributo
/**
* Método mágico: construtor
*/
public function __construct(string $password, string $username = 'danielhe4rt', float $money = 1500.0)
{
$this->username = $username; // Setter do Construtor
$this->password = password_hash($password, PASSWORD_ARGON2I); // Setter do Construtor
$this->money = $money; // Setter do Construtor
}
}// Instancia sem o valor do atributo username e o money
$danielhe4rt = new Player('secret123');
$danielhe4rt->username; // danielhe4rt
$danielhe4rt->money; // 1500.0Construtores são bem simples assim que você entende algumas regras e há muito mais a ser explorado, mas vamos manter isso simples!
Já os destrutores agem no momento oposto aos construtores, bem antes da classe ser removida da memória, sendo atribuídas null ou usando unset. Suas ações devem ser definidas no metódo __destruct.
class Player
{
public string $username; // propriedade/atributo
/**
* Método mágico: construtor
*/
public function __construct(string $username)
{
$this->username = $username; // Setter do Construtor
echo "Jogador Cadastrado!";
}
/**
* Método mágico: destrutor
*/
public function __destruct()
{
echo "Conta do jogador " . $this->username . " encerrada!";
}
}Note que deixei a classe bem sucinta e coloquei um echo para quando a classe é construida e quando a variável que recebe o objeto é removida da memória para dar um exemplo de como acontece o processo. Se liga:
$danielhe4rt = new Player('danielhe4rt');
// Jogador Cadastrado!
unset($danielhe4rt);
// Conta do jogador danielhe4rt encerrad!
- Ambos os metódos demostrados acima não devem retornar ou especificar tipo de retorno(apesar deste ser
voidpor padrão).- Classes que herdam outras usarão o construtor da classe-pai caso não definam um construtor próprio.
Ir para: 4.3 Herança