Oi Franklin,
esses dois métodos:
public function __set($nome, $valor)
{
$this->$nome = $valor;
}
public function __get($nome)
{
return $this->$nome;
}
Não são métodos mágicos, pois não fazem parte da API da linguagem. Inclusive, criar um getter e um setter só pra todos os atributos usando reflexão interpretada não é visto como uma boa prática.
Isso porque, caso esse código cresça e surjam regras de negocio especificas na definição ou busca do valor de um atributo a gente precisaria fazer verificações no getter/setter para descobrir qual atributo está sendo passado por parâmetro. Algo como:
public function __set($nome, $valor)
{
if($nome == "preco" && $valor > 0)
$this->$nome = $valor;
else if($nome == "preco")
throw new Exception("o preço do produto não pode ser negativo");
// a mesma ideia se repete pra qualquer outro atributo
}
Quanto a herança desse método. Teoricamente, não há problema algum utilizar os métodos explicitamente dentro da classe filha:
class Livro extends Produto
{
private $isbn;
public function calculaImposto()
{
return $this->__get("preco") * 0.065;
}
}
O problema aqui é que estamos tentando acessar a propriedade privada preço, fora da classe na qual ela foi declarada:
class Livro extends Produto
{
private $isbn;
public function calculaImposto()
{
return $this->preco * 0.065;
}
}
Nesse caso, para que o atributo seja visivel na classe filha, ele precisa estar declarado como protegido:
class Produto
{
private $id;
private $nome;
// agora esse atributo é visivel nas classes filhas tb =)
protected $preco;
private $descricao;
private $categoria;
private $usado;
...
Abraço!