Menu
Coddy logo textTech

Classes e Métodos Abstratos

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 32 de 87.

Às vezes, você deseja definir uma classe que sirva como um modelo, mas que nunca deva ser instanciada diretamente. Por exemplo, uma classe Shape genérica faz sentido como uma classe pai, mas como seria uma "forma" sem uma forma específica? É aqui que as classes abstratas entram.

Uma classe abstrata é declarada com a palavra-chave abstract e não pode ser instanciada. Ela pode conter tanto métodos regulares com implementações quanto métodos abstratos que não possuem corpo:

public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // Método abstrato - sem implementação
    public abstract double getArea();
    
    // Método regular - possui implementação
    public String getColor() {
        return color;
    }
}

Métodos abstratos declaram o que uma subclasse deve fazer, mas não como. Qualquer classe não abstrata que estenda uma classe abstrata deve fornecer implementações para todos os métodos abstratos:

public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

Você ainda pode usar classes abstratas como tipos de referência, permitindo o polimorfismo:

Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea());  // Chama a implementação do Circle

Classes abstratas são ideais quando subclasses compartilham código comum, mas cada uma deve implementar certos comportamentos de forma diferente. Elas impõem um contrato enquanto permitem a reutilização de código.

challenge icon

Desafio

Fácil

Vamos criar um sistema de eletrodomésticos que demonstra o poder das classes abstratas. Você criará uma classe base Appliance que define o que todo eletrodoméstico deve fazer, enquanto permite que tipos específicos de eletrodomésticos decidam exatamente como fazer isso.

Você organizará seu código em quatro arquivos:

  • Appliance.java: crie uma classe abstrata que sirva como modelo para todos os eletrodomésticos. Todo eletrodoméstico tem um campo brand (String) e um campo wattage (int). Inclua um construtor que inicialize ambos os campos, métodos getter para cada um e um método comum getInfo() que retorne: [brand] - [wattage]W. Defina um método abstrato operate() que as subclasses deverão implementar — ele representa como cada eletrodoméstico executa sua função principal.
  • WashingMachine.java: crie uma classe concreta que estenda Appliance. Máquinas de lavar têm um campo adicional capacity (int), que representa o tamanho da carga em kg. Use super para cuidar da inicialização da classe pai. Implemente o método operate() para imprimir: [brand] washing machine is washing [capacity]kg of clothes
  • Microwave.java: crie outra classe concreta que estenda Appliance. Micro-ondas têm um campo power (int), que representa o percentual do nível de potência. Implemente operate() para imprimir: [brand] microwave is heating at [power]% power
  • Main.java: reúna tudo usando polimorfismo. Você receberá cinco entradas: um nome de marca, a potência em watts, a capacidade da máquina de lavar, outro nome de marca e o nível de potência do micro-ondas. Crie uma WashingMachine e um Microwave e, em seguida, armazene-os em um array de referências Appliance. Percorra o array e, para cada eletrodoméstico, imprima suas informações usando getInfo(), seguido da chamada de operate().

Você receberá cinco entradas nesta ordem: primeira marca (String), primeira potência em watts (int), capacidade em kg (int), segunda marca (String) e nível de potência (int).

Sua saída deverá mostrar quatro linhas — para cada eletrodoméstico, você verá sua linha de informações seguida de seu comportamento de operação. Observe como a classe abstrata permite tratar diferentes eletrodomésticos de maneira uniforme, enquanto cada um funciona de sua própria maneira única!

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Ler as entradas
        String brand1 = scanner.nextLine();
        int wattage1 = scanner.nextInt();
        int capacity = scanner.nextInt();
        scanner.nextLine(); // consumir a quebra de linha
        String brand2 = scanner.nextLine();
        int power = scanner.nextInt();
        
        // TODO: Criar um objeto WashingMachine com brand1, wattage1 e capacity
        
        // TODO: Criar um objeto Microwave com brand2, wattage1 (ou a potência apropriada) e power
        
        // TODO: Criar um array de referências Appliance e armazenar ambos os objetos
        
        // TODO: Percorrer o array e para cada eletrodoméstico:
        // - Imprimir suas informações usando getInfo()
        // - Chamar operate()
    }
}
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

Pratique por conta própria: Compilador de Java online