Sobes.tech
Middle

Isto significa que a classe é imutável se tiver uma propriedade pública na classe?

sobes.tech IA

Resposta da IA

Não.

Uma propriedade pública numa classe significa que o valor dessa propriedade pode ser alterado de fora do objeto. Um objeto imutável é aquele cujo estado (valores das suas propriedades) não pode ser alterado após a sua criação. A presença de uma propriedade pública contradiz o princípio da imutabilidade.

Para alcançar a imutabilidade, a classe deve cumprir as seguintes condições:

  • Todas as propriedades devem ser privadas (private) ou protegidas (protected).
  • Não deve haver setters (métodos que alterem os valores das propriedades).
  • Todas as dependências (objetos com os quais a classe trabalha) também devem ser imutáveis ou o seu estado não deve ser alterado de fora.
  • O construtor deve inicializar completamente o objeto e não deve ser alterado após a sua criação.
  • Se forem necessárias alterações, devem ser criadas novas instâncias do objeto com os novos valores.

Exemplo de uma classe com uma propriedade pública (mutável):

<?php
class MutableObject
{
    public $value; // Propriedade pública

    public function __construct($value)
    {
        $this->value = $value;
    }
}

$obj = new MutableObject(10);
echo $obj->value; // 10

$obj->value = 20; // Valor alterado de fora
echo $obj->value; // 20

Exemplo de implementação de uma classe imutável:

<?php
class ImmutableObject
{
    private $value; // Propriedade privada

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function getValue() : int
    {
        return $this->value;
    }

    // Método para "alterar", na realidade cria um novo objeto
    public function withValue(int $newValue) : self
    {
        return new self($newValue);
    }
}

$obj1 = new ImmutableObject(10);
echo $obj1->getValue(); // 10

// $obj1->value = 20; // Erro: Não é possível aceder à propriedade privada

$obj2 = $obj1->withValue(20); // Cria um novo objeto
echo $obj1->getValue(); // 10 (objeto original não mudou)
echo $obj2->getValue(); // 20 (novo objeto com o valor alterado)