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 esse 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 da herança com requisitos obrigatórios. Use-as quando quiser compartilhar código entre classes relacionadas, garantindo que determinados métodos sejam implementados por cada classe filha.
Desafio
FácilVamos criar um sistema de reprodutor de mídia que demonstra como classes abstratas impõem um contrato e, ao mesmo tempo, permitem 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 sirva 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 deverão implementar. Adicione também um método comumgetTitle()que retorne o título. Esse método concreto será herdado por todas as classes filhas.Song.php: Defina uma classeSongque estendaMedia. Inclua o arquivo Media no início. Essa 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. Implemente o método obrigatórioplay()para retornar"Playing song: [title] by [artist]".Podcast.php: Defina uma classePodcastque estendaMedia. Inclua o arquivo Media no início. Essa classe adiciona uma propriedade$episode(um 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étodo obrigatórioplay()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 a ser convertida em um inteiro). Crie um objeto Song e um objeto Podcast com esses valores. Imprima primeiro o resultado da chamada de play() na música e, depois, no podcast, cada um em sua própria linha.
Este desafio mostra como classes abstratas definem um contrato: todo tipo de mídia deve ter um método play(), mas cada tipo o implementa de maneira diferente. A classe abstrata Media não pode ser instanciada diretamente; ela existe apenas para fornecer estrutura e funcionalidades compartilhadas às suas classes filhas.
Experimente você mesmo
<?php
require_once 'Song.php';
require_once 'Podcast.php';
// Ler 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 de chamar play() na song
// TODO: Imprimir o resultado de chamar 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 OOP
Arquivos externosIntrodução à OOPClasses vs. objetosA palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodosA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em ProfundidadeGetters e SettersOcultação de InformaçõesPromoção de Construtor (8.0)Recapitulação - Sistema de Registros de Alunos10Conceitos Avançados de OOP
Composição vs. HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibras (PHP 8.1)Análise Profunda da 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 às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataTipagem 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 NulosTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadaTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários3Propriedades de Classes
Propriedades de Instância vs. EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Somente para Leitura (PHP 8.1)Recapitulação - Gerenciador de Contas Bancárias6Polimorfismo
Revisão da Sobrescrita de MétodosPolimorfismo via InterfacesIndicação de Tipos e Tipos UnionVinculação Estática TardiaRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos entre 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 StrategyPratique por conta própria: Compilador de PHP online