Fácil Java

Formas geométricas com classe abstrata

Enunciado

Crie uma classe abstrata Forma com um método abstrato area() e um método concreto descricao() que imprime "Área: " seguido do valor retornado por area(). Depois, implemente as classes Circulo e Quadrado que estendem Forma. No main, crie uma instância de cada e chame descricao().

Requisitos

  • A classe Forma deve ser abstrata e ter o método abstrato area().
  • Circulo e Quadrado devem sobrescrever area() corretamente.
  • O método descricao() deve ser concreto e reutilizado por ambas as subclasses.
  • A saída deve mostrar a área do círculo e do quadrado.

Código inicial

abstract class Forma {
    public abstract double area();

    public void descricao() {
        // implemente aqui
    }
}

class Circulo extends Forma {
    private double raio;

    public Circulo(double raio) {
        this.raio = raio;
    }

    @Override
    public double area() {
        // implemente aqui
        return 0;
    }
}

class Quadrado extends Forma {
    private double lado;

    public Quadrado(double lado) {
        this.lado = lado;
    }

    @Override
    public double area() {
        // implemente aqui
        return 0;
    }
}

public class Main {
    public static void main(String[] args) {
        Forma c = new Circulo(2.0);
        Forma q = new Quadrado(3.0);
        c.descricao();
        q.descricao();
    }
}

Saída esperada

Área: 12.566370614359172
Área: 9.0
Ver dica

Use Math.PI * raio * raio para a área do círculo e lado * lado para o quadrado. No método descricao(), chame area() e concatene com a string.

Mostrar solução
abstract class Forma {
    public abstract double area();

    // Método concreto que usa o método abstrato area()
    public void descricao() {
        System.out.println("Área: " + area());
    }
}

class Circulo extends Forma {
    private double raio;

    public Circulo(double raio) {
        this.raio = raio;
    }

    @Override
    public double area() {
        return Math.PI * raio * raio;
    }
}

class Quadrado extends Forma {
    private double lado;

    public Quadrado(double lado) {
        this.lado = lado;
    }

    @Override
    public double area() {
        return lado * lado;
    }
}

public class Main {
    public static void main(String[] args) {
        Forma c = new Circulo(2.0);
        Forma q = new Quadrado(3.0);
        c.descricao();
        q.descricao();
    }
}

Passo a passo

  1. Declaramos Forma como abstract, impedindo que seja instanciada diretamente.
  2. O método area() é abstrato: não tem corpo e obriga as subclasses a implementá-lo.
  3. O método descricao() é concreto e chama area() dinamicamente, aproveitando o polimorfismo.
  4. Circulo guarda o raio e calcula a área com Math.PI * raio * raio.
  5. Quadrado guarda o lado e calcula a área com lado * lado.
  6. No main, criamos referências do tipo Forma apontando para objetos concretos.
  7. Ao chamar descricao(), o método area() correto é invocado em tempo de execução.

Por que funciona

A classe abstrata define o contrato area() e fornece a implementação comum descricao(). As subclasses só precisam se preocupar com o cálculo específico. Isso demonstra o poder das classes abstratas: reutilizar código e garantir que certos métodos sejam implementados.

Erros comuns

  • Esquecer de implementar area() em uma subclasse: o compilador acusa erro porque a subclasse concreta deve implementar todos os métodos abstratos.
  • Tentar instanciar Forma diretamente: new Forma() causa erro de compilação.
  • Declarar descricao() como abstrato sem necessidade: perderia o reuso do código comum.

Outra forma de resolver

Poderia ser usado um record para formas imutáveis, mas classes abstratas ainda são mais flexíveis quando há estado mutável ou hierarquias mais complexas.

Saída esperada

Área: 12.566370614359172
Área: 9.0