Menu
Coddy logo textTech

Modificadores de Acesso em Detalhes

Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 39 de 91.

Agora que você entende os três modificadores de acesso, vamos explorar como eles se comportam em cenários de herança. O ponto principal é que os membros protected tornam-se acessíveis às classes filhas, enquanto os membros private permanecem ocultos mesmo para as filhas.

<?php
class Vehicle {
    public $brand;
    protected $engineType;
    private $serialNumber;
    
    public function __construct($brand, $engine, $serial) {
        $this->brand = $brand;
        $this->engineType = $engine;
        $this->serialNumber = $serial;
    }
    
    private function getSerial() {
        return $this->serialNumber;
    }
    
    protected function getEngineInfo() {
        return $this->engineType;
    }
}

class Car extends Vehicle {
    public function getDetails() {
        return $this->brand . " - " . $this->getEngineInfo();
        // $this->serialNumber causaria um erro - privado!
        // $this->getSerial() também falharia - método privado!
    }
}

$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails();

Saída:

Toyota - V6

A classe Car pode acessar $brand (público) e chamar getEngineInfo() (protegido), mas não tem acesso a $serialNumber ou getSerial() porque eles são privados para Vehicle. Essa distinção permite que você compartilhe alguns detalhes internos com classes filhas, mantendo outros completamente ocultos.

Ponto Chave: Use protected quando as classes filhas precisarem de acesso a dados ou métodos internos, e private quando mesmo as classes filhas não devam tocar em certos detalhes de implementação.

challenge icon

Desafio

Fácil

Vamos construir um sistema de gerenciamento de dispositivos que explora como os modificadores de acesso se comportam através da herança. Você criará uma classe base Device com propriedades em diferentes níveis de visibilidade e, em seguida, a estenderá com uma classe Smartphone que demonstra quais membros as classes filhas podem ou não acessar.

Você organizará seu código em três arquivos:

  • Device.php — Crie uma classe Device que represente dispositivos eletrônicos com níveis variados de sensibilidade de dados. Inclua:
    • Uma propriedade public $brand para o nome do fabricante
    • Uma propriedade protected $modelNumber para identificação interna
    • Uma propriedade private $manufacturingCode para dados exclusivos da fábrica
    O construtor deve aceitar todos os três valores. Adicione um método private getManufacturingCode() que retorna o código de fabricação. Adicione um método public getModelInfo() que retorna "Model: [modelNumber]". Por fim, adicione um método public getFullCode() que retorna "[brand]-[manufacturingCode]" — isso demonstra como a própria classe pode acessar seus próprios membros privados.
  • Smartphone.php — Crie uma classe Smartphone que estenda Device. Inclua o arquivo Device. O construtor deve aceitar brand, modelNumber, manufacturingCode e o nome de um sistema operacional. Chame o construtor pai com os três primeiros valores e, em seguida, armazene o OS em uma propriedade privada. Adicione um método público getDeviceDetails() que retorna "[brand] [modelNumber] running [os]". Observe como você pode acessar o $brand público diretamente e o $modelNumber protegido, mas não pode acessar o $manufacturingCode privado diretamente — você precisaria usar o método público herdado getFullCode() em vez disso.
  • main.php — Inclua o arquivo Smartphone. Você receberá quatro entradas: um nome de marca, um número de modelo, um código de fabricação e um sistema operacional. Crie uma instância de Smartphone com esses valores. Imprima três linhas:
    • O resultado da chamada de getDeviceDetails()
    • O resultado da chamada do método herdado getModelInfo()
    • O resultado da chamada do método herdado getFullCode()

Este desafio destaca a distinção fundamental: sua classe Smartphone pode usar livremente o $modelNumber protegido herdado de Device, mas o $manufacturingCode privado e o getManufacturingCode() permanecem completamente ocultos — acessíveis apenas através da interface pública que a Device escolhe expor.

Folha de consulta

Na herança, membros protected são acessíveis às classes filhas, enquanto membros private permanecem ocultos até mesmo para as filhas.

<?php
class Vehicle {
    public $brand;
    protected $engineType;
    private $serialNumber;
    
    public function __construct($brand, $engine, $serial) {
        $this->brand = $brand;
        $this->engineType = $engine;
        $this->serialNumber = $serial;
    }
    
    private function getSerial() {
        return $this->serialNumber;
    }
    
    protected function getEngineInfo() {
        return $this->engineType;
    }
}

class Car extends Vehicle {
    public function getDetails() {
        return $this->brand . " - " . $this->getEngineInfo();
        // $this->serialNumber causaria um erro - private!
        // $this->getSerial() também falharia - método privado!
    }
}

$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails(); // Toyota - V6

As classes filhas podem acessar:

  • Propriedades e métodos public
  • Propriedades e métodos protected

As classes filhas não podem acessar:

  • Propriedades e métodos private (estes permanecem exclusivos da classe pai)

Melhor Prática: Use protected quando as classes filhas precisarem de acesso a dados ou métodos internos, e private quando nem mesmo as classes filhas devam tocar em certos detalhes de implementação.

Experimente você mesmo

<?php
require_once 'Smartphone.php';

// Ler as entradas
$brand = trim(fgets(STDIN));
$modelNumber = trim(fgets(STDIN));
$manufacturingCode = trim(fgets(STDIN));
$os = trim(fgets(STDIN));

// TODO: Criar uma instância de Smartphone com os valores de entrada

// TODO: Imprimir o resultado de getDeviceDetails()

// TODO: Imprimir o resultado do método herdado getModelInfo()

// TODO: Imprimir o resultado do método herdado getFullCode()
?>
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos