Médio PHP
Conta bancária imutável com readonly class
Enunciado
Transforme a classe Conta em uma readonly class com as propriedades titular (string) e saldo (float). Adicione um método depositar(float $valor): self que retorna uma nova instância com o saldo somado, sem alterar a original. Imprima o saldo da conta original e da nova.
Requisitos
- A classe deve ser declarada como
readonly class. - O método
depositardeve retornar uma nova instância (return new self(...)). - A conta original não deve ser alterada.
- O programa deve imprimir os dois saldos com
number_format.
Código inicial
<?php
declare(strict_types=1);
class Conta
{
// TODO: tornar readonly e implementar depositar
}
$c = new Conta('Ana', 1000.0);
$c2 = $c->depositar(500.0);
echo number_format($c->saldo, 2, ',', '.'), PHP_EOL;
echo number_format($c2->saldo, 2, ',', '.'), PHP_EOL;
Saída esperada
1.000,00
1.500,00
Ver dica
Em readonly class, todas as propriedades são readonly automaticamente. Para "alterar", retorne uma nova instância.
Mostrar solução
<?php
declare(strict_types=1);
// readonly class: TODAS as propriedades são readonly
readonly class Conta
{
public function __construct(
public string $titular,
public float $saldo,
) {}
// Não muta: devolve uma nova Conta com o saldo atualizado
public function depositar(float $valor): self
{
return new self($this->titular, $this->saldo + $valor);
}
}
$c = new Conta('Ana', 1000.0);
$c2 = $c->depositar(500.0);
echo number_format($c->saldo, 2, ',', '.'), PHP_EOL;
echo number_format($c2->saldo, 2, ',', '.'), PHP_EOL;
Passo a passo
readonly class Contamarca automaticamentetitularesaldocomo readonly.- O construtor promovido recebe e atribui os dois valores.
depositar()não altera$this->saldo; cria uma nova instância com o valor somado.- Como
selfé uma referência à própria classe,new self(...)funciona dentro dela. - No programa principal, guardamos a nova conta em
$c2e imprimimos os dois saldos formatados.
Por que funciona
A imutabilidade impede que depositar modifique o objeto original. Cada operação devolve uma nova versão, o que torna o fluxo previsível e evita efeitos colaterais em outros pontos do código que compartilhem a mesma referência.
Erros comuns
- Escrever
$this->saldo += $valor;dentro dedepositar: lançaError: Cannot modify readonly property. - Declarar
readonly classe ainda colocarreadonlyem cada propriedade: redundante, gera erro de sintaxe em algumas versões. - Esquecer
returnna nova instância: o método retornanulle quebra o tipoself.
Outra forma de resolver
Usar uma propriedade readonly isolada em vez da classe inteira:
class Conta {
public function __construct(
public readonly string $titular,
public readonly float $saldo,
) {}
// ...
}
Prefira isso quando só algumas propriedades precisam ser imutáveis.
Saída esperada
1.000,00
1.500,00