Classes Abstratas
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 25 de 91.
Uma classe abstrata é uma classe que não pode ser instanciada diretamente. Ela serve como um modelo para outras classes, definindo métodos que as classes filhas devem implementar. Você cria uma classe abstrata usando a palavra-chave abstract.
<?php
abstract class Shape {
protected $color;
public function __construct($color) {
$this->color = $color;
}
abstract public function calculateArea();
public function getColor() {
return $this->color;
}
}
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($color, $width, $height) {
parent::__construct($color);
$this->width = $width;
$this->height = $height;
}
public function calculateArea() {
return $this->width * $this->height;
}
}
$rect = new Rectangle("blue", 5, 3);
echo $rect->calculateArea();
Saída:
15A classe Shape declara um método abstrato calculateArea() sem fornecer uma implementação. Qualquer classe que estenda Shape deve implementar este método. Observe que classes abstratas também podem conter métodos regulares como getColor() que as classes filhas herdam diretamente.
Métodos abstratos definem o que uma classe filha deve fazer, mas não como. Isso garante que todas as formas tenham um método calculateArea(), permitindo que cada forma calcule sua área de maneira diferente.
Ponto Chave: Classes abstratas combinam a estrutura de herança com requisitos obrigatórios. Use-as quando quiser compartilhar código entre classes relacionadas, garantindo que certos métodos sejam implementados por cada classe filha.
Desafio
FácilVamos construir um sistema de player de mídia que demonstra como classes abstratas impõem um contrato, permitindo que diferentes tipos de mídia implementem seu próprio comportamento de reprodução.
Você organizará seu código em três arquivos:
Media.php— Defina uma classe abstrataMediaque serve como modelo para todos os tipos de mídia. Ela deve ter uma propriedade protegida$titlee um construtor que aceite e defina o título. Inclua um método abstrato chamadoplay()que as classes filhas devem implementar. Adicione também um método regulargetTitle()que retorna o título — este método concreto será herdado por todas as classes filhas.Song.php— Defina uma classeSongque estendeMedia. Inclua o arquivo Media no topo. Esta classe adiciona uma propriedade$artist. O construtor deve aceitar o título e o artista — useparent::__construct()para o título e, em seguida, defina o artista você mesmo. Implemente o métodoplay()obrigatório para retornar"Playing song: [title] by [artist]".Podcast.php— Defina uma classePodcastque estendeMedia. Inclua o arquivo Media no topo. Esta classe adiciona uma propriedade$episode(um número inteiro). O construtor deve aceitar o título e o número do episódio — useparent::__construct()para o título e, em seguida, defina o episódio. Implemente o métodoplay()obrigatório para retornar"Playing podcast: [title] - Episode [episode]".
Em main.php, inclua os arquivos Song e Podcast. Você receberá quatro entradas: o título da música, o nome do artista, o título do podcast e o número do episódio (como uma string para converter em um número inteiro). Crie um objeto Song e um objeto Podcast com esses valores. Imprima o resultado da chamada de play() na música primeiro, depois no podcast, cada um em sua própria linha.
Este desafio mostra como as classes abstratas definem um contrato — cada tipo de mídia deve ter um método play(), mas cada tipo o implementa de forma diferente. A classe abstrata Media não pode ser instanciada diretamente; ela existe apenas para fornecer estrutura e funcionalidade compartilhada para seus filhos.
Folha de consulta
Uma classe abstrata é uma classe que não pode ser instanciada diretamente. Ela serve como um modelo para outras classes, definindo métodos que as classes filhas devem implementar. Use a palavra-chave abstract para criar uma classe abstrata.
abstract class Shape {
protected $color;
public function __construct($color) {
$this->color = $color;
}
abstract public function calculateArea();
public function getColor() {
return $this->color;
}
}As classes filhas devem implementar todos os métodos abstratos:
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($color, $width, $height) {
parent::__construct($color);
$this->width = $width;
$this->height = $height;
}
public function calculateArea() {
return $this->width * $this->height;
}
}Características principais:
- Classes abstratas não podem ser instanciadas diretamente
- Métodos abstratos não possuem implementação na classe abstrata
- Classes filhas devem implementar todos os métodos abstratos
- Classes abstratas podem conter tanto métodos abstratos quanto métodos regulares
- Métodos regulares em classes abstratas são herdados pelas classes filhas
Experimente você mesmo
<?php
require_once 'Song.php';
require_once 'Podcast.php';
// Ler as entradas
$songTitle = trim(fgets(STDIN));
$artistName = trim(fgets(STDIN));
$podcastTitle = trim(fgets(STDIN));
$episodeNumber = intval(trim(fgets(STDIN)));
// TODO: Criar um objeto Song com songTitle e artistName
// TODO: Criar um objeto Podcast com podcastTitle e episodeNumber
// TODO: Imprimir o resultado da chamada de play() na música
// TODO: Imprimir o resultado da chamada de play() no podcast
?>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
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodoA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em DetalhesGetters e SettersOcultação de InformaçãoPromoção de Construtor (8.0)Recapitulação - Sistema de Registro de Alunos10Conceitos Avançados de POO
Composição vs HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibers (PHP 8.1)Mergulho Profundo em Clonagem de ObjetosGeradores e Iteradores13Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository2Namespaces e Autoloading
Introdução a NamespacesA Palavra-chave usePadrão de Autoloading PSR-4Autoloader do ComposerRecapitulação - Projeto Organizado5Interfaces e Contratos
Introdução a InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataType Hinting com InterfacesRecapitulação - Calculadora de Formas8Métodos Mágicos
Introdução aos Métodos Mágicos__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e Clonagem de Objetos__serialize e __unserializeRecapitulação - Coleção Personalizada11Sistema de Tipos e Tratamento de Erros
Declarações de TiposTipos AnuláveisTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadasTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário3Propriedades de Classe
Propriedades de Instância vs EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Readonly (PHP 8.1)Recapitulação - Gerenciador de Conta Bancária6Polimorfismo
Sobrescrita de Métodos RevisitadaPolimorfismo via InterfacesType Hinting e Union TypesLate Static BindingRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos de TraitsMétodos Abstratos em TraitsTraits vs Herança12Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy