• Conceitos de P.O.O

Clique sobre os tópicos listados abaixo para navegar até o conteúdo desejado.

  1. Herança de classe
  2. Construtor e herança
  3. Uso de parent e self
  4. Modificador protected
  5. Polimorfisno
  6. Herança múltipla
  7. Entender o uso do self

Os assuntos sobre herança de interface e herança múltipla será abordado em POO: Interface e Classe Abstrata, pois é necessário o conhecimentos básico sobre uso de interfaces.

Outro conceito de O.O que vamos aplicar na linguagem PHP é o conceito de herança que pode ser resumido a um relacionamento "é-um" em que uma classe filha herda características de uma classe pai podendo utilizar os recursos dessa classe e também estendê-la.

A sintaxe para a utilização de herança entre classes na Linguagem PHP é feita da forma simples como mostrado abaixo utilizando a palavra reservada extends:

Sintaxe
class nome_classe_filha extends nome_classe_pai {
  //corpo
}
Onde
extends: Palavra reservada para definir o uso de herança

Não há diferença na instanciação de um objeto utilizando uma classe que usa o conceito de herança, a palavra reservada new é utiliza da mesma forma.

Os termos Pai(parent) e Filha(child) acima serão utilizados ao longo deste trecho do tutorial em que vamos estudar a herança entre classes para facilitar a compreensão.

Exemplo 1
<?php
    //main.php
    class Pai{
        //omitido
    }
    
    class Filha extends Pai{
        //omitido
    }
    
    $pai = new Pai();
    $filha = new Filha();
?>
Saída
-

Os métodos construtores tipo padrão, sem parâmetros, são chamados implicitamente quando instanciamos um objeto da classe Filha que utiliza herança.

Exemplo 2
<?php
    //main.php
    class Pai{
        //corpo omitido
    }
    
    class Filha extends Pai{
        //corpo omitido
    }
    
    $pai = new Pai();
    $filha = new Filha();
?>
Saída
-

Ao ser chamado o construtor padrão da classe Filha, o construtor da classe Pai é chamado implicitamente sem a necessidade codificação. O construtor de uma classe Pai é chamado utilizando parent.

Sintaxe
class classe_filha extends classe_pai
{
    function __construct()
    {
        parent::__construct();
    }
}
Saída
-

Quando o método __construct da classe Pai possui argumentos, a chamada a esse método deve ser feita de forma explícita passando os argumentos necessários.

Sintaxe
class classe_filha extends classe_pai
{
    function __construct(<parametros>)
    {
        parent::__construct(<parametros>);
    }
}
Exemplo 3
<?php
    //main.php
    class Pai{
        public $atributoPai = 0;
        
        function __construct($param){
            $this->atributoPai = $param;
        }
    }
    
    class Filha extends Pai{
        public $atributoFilha = 0;
       
        function __construct($param,$param2){
            $this->atributoFilha = $param2;
            parent::__construct($param);
        }
    }
    
    $pai = new Pai(999);
    $filha = new Filha(999,888);
?>
Saída
-

A palavras reservadas parent e self dizem respeito ao uso de recursos de uma classe Pai e e Filha respectivamente. Quando essas classes, por exemplo, possuem métodos ou atributos homônimos, a distinção entre esses é feita utilizando essas palavras reservadas.

Sintaxe
parent::nome_metodo(<argumentos>);
Sintaxe
self::nome_metodo(<argumentos>);

O acesso aos recursos da classe Pai(parent) são controlados pelo uso dos modificadores de acesso private, public e protected.

A palavra parent só podem ser utilizados quando há a extensão da classe utilizando extends. Já a self pode ser utilizado sem herança.

Exemplo 5
<?php
    //main.php
    class Pai{
        public function metodo(){
            echo "Pai::metodo","\n";
        }
    }
    
    class Filha extends Pai{
        public function metodo(){
            echo "Filha::metodo","\n";
        }       
        public function metodoFilha(){
            echo "Filha::metodoFilha","\n";
            parent::metodo();
            self::metodo();
        }
    }
    
    $filha = new Filha();
    $filha->metodoFilha();
    
?>
Saída
Filha::metodoFilha
Pai::metodo
Filha::metodo

Com o uso de herança vamos aprender um novo modificador de acesso chamado protected. Esse modificador permite que o acesso aos atributos de uma classe Pai seja permitida apenas por suas classes filhas.

Sintaxe
class nome_classe 
{
    protected function nome_metodo(<argumentos>)
    {
        //omitido
    }
}
parent::nome_metodo(<argumentos>);

Para que a classe Filha tenha acesso aos atributos de sua classe Pai, precisamos utilizar a palavra reservada parent em conjunto com o operador de acesso (::). Esse acesso deve ser feito dentro de um método.

Exemplo 6
<?php
    //main.php
    class Pai{
        protected $atributo = "Pai";
        
        protected function metodo1(){
          echo "Pai: metodo()","\n";
        }
    }
    class Filha extends Pai{
    
        public function metodo3(){
          echo "metodo3()","\n";
          parent::metodo1(); //método da classe pai via parent
        }
    }
    $f = new Filha();
    $f->metodo3();
?>
Saída
metodo3()
Pai: metodo()

Como a classe filha herda os atributos e métodos de sua classe Pai, é possível acessar métodos e atributos utilizando a palavra reservada this.

Exemplo 7
<?php
    //main.php
    class Pai{
        protected $atributo = "Pai";
        
        protected function metodo1(){
          echo "Pai: metodo()","\n";
        }
        
        //visível apenas na classe Pai
        private function metodo2(){
            //omitido
        }
    }
    class Filha extends Pai{
    
        public function metodo3(){
          echo "metodo3()","\n";
          echo "atributo:", $this->atributo,"\n";
          $this->metodo1(); ////método da classe pai via $this
          //$this->metodo2(); //private, não pode ser invocado
        }
    }
    $f = new Filha();
    $f->metodo3();
Saída
metodo3()
atributo:Pai
Pai: metodo()

Polimorfismo consiste em um classe Filha sobrescrever a implementação de um método herdado da classe Pai. Dessa forma, uma classe Filha pode utilizar um ou mais métodos com a mesma assinatura, porém com comportamentos diferentes.

O que foi discutido acima é colocado em prática com a sobrescrita de métodos nos exemplos 8 e 9 mostrados abaixo:

Exemplo 8: Sem polimorfismo
<?php
    //main.php
    class Pai
    {
        public $atributo = 100;
        //construtor omitido
        public function metodo(){
          echo "Pai: metodo()","\n";
          echo $this->atributo,"\n";
        }
    }
    class Filha extends Pai{
    //construtor omitido
    }

    //chamada ao método da classe Pai por Filha
    $f = new Filha();
    $f->metodo();
?>
Saída
Pai: metodo()
100
Exemplo 9: Com polimorfismo
<?php
    //main.php
    class Pai
    {
        public $atributo = 100;

        //método que será sobrescrito
        public function metodo(){
          echo "Pai: metodo()","\n";
          echo $this->atributo,"\n";
        }
    }

    class Filha extends Pai{

        //método sobrescrito
        public function metodo(){
          echo "Filha: metodo()","\n";
          echo $this->atributo*2,"\n";
        }
    }
    $p = new Pai();
    $p->metodo();
    $f = new Filha();
    $f->metodo();
?>
Saída
Pai: metodo()
100
Filha: metodo()
200

Por padrão, qualquer método que utiliza os modificadores de acesso public e protected pode sofrer polimorfismo quando sua classe for herdada.

Para evitar que um método não seja sobrescrito, a linguagem PHP possui é o modificador de restrição final que deve ser utilizado na declaração de um método.

Sintaxe
modificador_acesso final nome_metodo(<lista_parametros>)
{
   //omitido
}
Exemplo 10
<?php
//main.php
    class Pai
    {
        public $atributo = 100;

        //método que será sobrescrito
        public final function metodo(){
          echo "Pai: metodo()","\n";
          echo $this->atributo,"\n";
        }
    }

    class Filha extends Pai{

        //método sobrescrito
        public function metodo(){
          echo "Filha: metodo()","\n";
          echo $this->atributo*(0.10),"\n";
        }
    }

    $f = new Filha();
     //chamada ao método sobrescrito
    $f->metodo();
?>
Saída
PHP Fatal error:  Cannot override final method Pai::metodo() in main.php on line 17

A linguagem PHP não possui suporte a herança múltipla de classes. Essa herança é feita em combinação de herença de classe concreta e interface. As palavras reservadas extends e implements para mostram essa herança discutida:

Sintaxe
class classe_filha extends classe_pai implements <lista_interfaces>
{
    //corpo classe
}
Exemplo 11
<?php
//main.php
class Classe 
{
    //omitido
}
    
interface IClasse 
{
    //omitido
}

class ClasseFilha extends Classe implements IClasse
{
    //omitido
}
?>
Saída
-
  1. 26/08/2025 - revisão 4 - Ajustes: pontuais, objetivos, target de links e sintaxes;Adição: herança múltipla
  2. 20/09/2024 - revisão 3 - Correção em sintaxe 'Métodos Construtores e Herança', ajustes gramaticais e outros
  3. 03/09/2024 - revisão 2 - Correção em links de objetivos
  4. 05/02/2024 - revisão 1 - correção em navegação, exemplos self/parent,final e erros gramaticais
  5. 20/09/2023 - versão inicial