🚀 Capítulo 11: Classes Abstratas e Interfaces

🎯 Objetivo da Aula

Ao final desta aula, você será capaz de compreender a diferença entre Classes Abstratas e Interfaces, aplicando-as para criar contratos de comportamento e modelos padronizados de código.


🏢 O Cenário Prático (Seu Desafio)

Você é o operador Tank a bordo da nave Nabucodonosor (Matrix). O seu desafio é carregar programas de treinamento diretamente na mente de Neo. Para garantir que todos os programas de habilidades funcionem perfeitamente no conector cerebral, você deve usar Interfaces como plugues padrão e Classes Abstratas como base para os programas.


🧠 Fundamentos: A Teoria Traduzida

Às vezes, criamos classes que servem apenas como molde geral e nunca devem ser transformadas em objetos diretamente.

  • Classe Abstrata (abstract): É uma classe “incompleta”. Ela serve apenas para ser herdada. Pode conter métodos prontos e métodos abstratos (que as filhas são obrigadas a criar).
  • Interface: É um contrato puro. Ela não diz como fazer, apenas o que deve ser feito. É o plugue perfeito! Em Java, uma classe pode implementar várias interfaces.

Analogia da Matrix

Imagine o conector na nuca dos personagens. Qualquer cabo que se conecte ali deve seguir o padrão do conector (Interface). O que passa pelo cabo (o programa de Kung Fu ou de pilotar helicóptero) varia, mas o plugue é sempre o mesmo.

classDiagram
    class Habilidade {
        "<<interface>>"
        +carregar()
    }
    class KungFu {
        +carregar()
    }
    class PilotarHelicoptero {
        +carregar()
    }
    Habilidade <|.. KungFu : Implementa
    Habilidade <|.. PilotarHelicoptero : Implementa

📖 Exemplo Guiado

Vamos criar a interface de habilidades da Matrix.

  1. Crie o arquivo Habilidade.java (A Interface):
public interface Habilidade {
    // Métodos em interfaces são abstratos por padrão
    void carregar();
}
  1. Crie o arquivo KungFu.java (A classe que segue o contrato):
public class KungFu implements Habilidade {
    @Override
    public void carregar() {
        System.out.println("Eu sei lutar Kung Fu!");
    }
}
  1. Crie o arquivo Operador.java para testar o carregamento:
public class Operador {
    public static void main(String[] args) {
        // Usando o tipo da Interface para referenciar o objeto
        Habilidade programa = new KungFu();
        
        System.out.println("Tank: Carregando programa na mente de Neo...");
        programa.carregar();
    }
}

🕹️ Como Executar e Testar no VS Code

  1. Abra o arquivo Operador.java.
  2. Clique em Run logo acima do método main.

Resultado Esperado:

Tank: Carregando programa na mente de Neo...
Eu sei lutar Kung Fu!


🛠️ Prática Obrigatória 1

Crie uma classe abstrata chamada ProgramaTreinamento. Ela deve ter o atributo String nome e um método concreto exibirNome() (que apenas imprime o nome). Deve ter também um método abstrato void iniciar(). Crie uma classe filha concreta que herde dela e implemente o método iniciar().

Resultado Esperado:

ClasseMétodo ChamadoSaída Esperada
Filha de ProgramaTreinamentoexibirNome()[Nome do Programa]
iniciar()[Mensagem de início]

🛠️ Prática Obrigatória 2

Crie uma nova interface chamada Armamento. Ela deve ter o método void disparar(). Crie uma classe chamada CombateAvancado que implemente tanto Habilidade quanto Armamento (Simulando um programa completo de batalha).

Resultado Esperado:

ClasseMétodos ImplementadosComportamento Esperado
CombateAvancadocarregar() e disparar()Deve compilar e rodar com os dois comportamentos!

📤 Instruções de Entrega (GitHub Desktop + Microsoft Teams)

Neste curso, você entregará suas atividades enviando o código para o seu repositório no GitHub usando o aplicativo GitHub Desktop. Siga o passo a passo detalhado:

  1. Verifique a estrutura: Certifique-se de que sua estrutura de pastas final está idêntica à mostrada abaixo.
  2. Abra o GitHub Desktop: Certifique-se de que o repositório do seu curso está selecionado no canto superior esquerdo.
  3. Visualize as alterações: Na aba Changes (à esquerda), você verá todos os arquivos que criou ou modificou nesta aula.
  4. Faça o Commit:
    • No campo Summary (na parte inferior esquerda), digite uma mensagem curta descrevendo o que fez, ex: Finaliza atividades do Capítulo 11.
    • Clique no botão azul Commit to main (ou o nome da sua branch).
  5. Envie para a Nuvem (Push): No topo da tela, clique no botão Push origin. Isso enviará seu código do seu computador para o seu perfil no GitHub.
  6. ⚠️ IMPORTANTE (Repositório Público): Para que o professor consiga corrigir, o seu repositório no GitHub DEVE SER PÚBLICO. Repositórios privados não podem ser visualizados por quem não foi convidado.
  7. Como entregar no Microsoft Teams:
    • Copie o link do seu repositório no GitHub (ex: https://github.com/seu-usuario/seu-repositorio).
    • Abra a tarefa correspondente no Microsoft Teams.
    • Clique no botão Adicionar trabalho (ou Add work).
    • Selecione a opção Link no menu lateral.
    • Cole o link do GitHub no campo “Endereço Web” e digite um texto (ex: Meu Repositório) no campo “Texto a ser exibido”.
    • Clique em Anexar.
    • MUITO IMPORTANTE: Clique no botão Entregar (ou Turn in) no canto superior direito para concluir o envio!

💡 Checkpoint de Lógica

O que você acabou de fazer é criar uma arquitetura plugável. Em sistemas reais, interfaces são usadas para conectar diferentes bancos de dados ou meios de pagamento (Pix, Cartão). O sistema principal não quer saber como o pagamento é feito, apenas que ele segue a regra da interface!


🔥 Desafio de Fixação (Opcional)

Tente criar uma classe Personagem que tenha uma lista de Habilidade. Crie um método para adicionar habilidades a essa lista e outro para executar todas as habilidades carregadas.


🔑 Gabarito de Código/Fórmulas

Prática 1:

public abstract class ProgramaTreinamento {
    protected String nome;
 
    public ProgramaTreinamento(String nome) { this.nome = nome; }
 
    public void exibirNome() { System.out.println("Programa: " + nome); }
 
    public abstract void iniciar();
}
 
public class TreinamentoFisico extends ProgramaTreinamento {
    public TreinamentoFisico(String nome) { super(nome); }
 
    @Override
    public void iniciar() { System.out.println("Iniciando corrida na esteira virtual!"); }
}

Prática 2:

public interface Armamento {
    void disparar();
}
 
public class CombateAvancado implements Habilidade, Armamento {
    @Override
    public void carregar() { System.out.println("Técnicas de esquiva carregadas!"); }
 
    @Override
    public void disparar() { System.out.println("Disparando rajadas de metralhadora!"); }
}

Desafio:

import java.util.ArrayList;
import java.util.List;
 
public class Humano {
    private String nome;
    private List<Habilidade> mente = new ArrayList<>();
 
    public Humano(String nome) { this.nome = nome; }
 
    public void aprender(Habilidade h) { mente.add(h); }
 
    public void agir() {
        System.out.println(nome + " está agindo:");
        for (Habilidade h : mente) {
            h.carregar();
        }
    }
}

Capitulo Anterior | Proximo Capitulo