Crie a seguinte hierarquia de classes:
  • Uma interface para representar qualquer forma geométrica, definindo métodos para cálculo do perímetro e cálculo da área da forma;
  • Uma classe abstrata para representar quadriláteros. Seu construtor deve receber os tamanhos dos 4 lados e o método de cálculo do perímetro já pode ser implementado;
  • Classes para representar retângulos e quadrados. A primeira deve receber o tamanho da base e da altura no construtor, enquanto a segunda deve receber apenas o tamanho do lado;
  • Uma classe para representar um círculo. Seu construtor deve receber o tamanho do raio.
    No programa principal, pergunte ao usuário quantas formas ele deseja criar. Em seguida, para cada forma, pergunte se deseja criar um quadrado, um retângulo ou um círculo, solicitando os dados necessários para criar a forma. Finalmente, imprima: (a) os dados (lados ou raio); (b) os perímetros; e © as áreas de todas as formas.

Passo 1

Beleza, vamos lá! Você tem um exercício que pede para criar uma hierarquia de classes para representar formas geométricas. A gente vai precisar usar conceitos de Programação Orientada a Objetos (POO), como interfaces, classes abstratas e herança. Também vamos precisar saber como calcular perímetros e áreas de diferentes formas geométricas. Vamos organizar isso passo a passo!

Passo 2

Primeiro, vamos criar uma interface chamada FormaGeometrica. Uma interface serve como um contrato, ou seja, todas as classes que implementarem essa interface precisam ter os métodos definidos nela. No nosso caso, vamos definir dois métodos: calcularPerimetro() e calcularArea().
public interface FormaGeometrica {
    double calcularPerimetro();
    double calcularArea();
}

Passo 3

Agora, vamos criar uma classe abstrata chamada Quadrilatero. Classes abstratas servem como modelos para outras classes e podem conter métodos implementados ou não. No caso dos quadriláteros, sabemos que o perímetro é a soma dos quatro lados, então podemos implementar esse método aqui. Também vamos declarar os lados como atributos.
public abstract class Quadrilatero implements FormaGeometrica {
    protected double lado1, lado2, lado3, lado4;

    public Quadrilatero(double lado1, double lado2, double lado3, double lado4) {
        this.lado1 = lado1;
        this.lado2 = lado2;
        this.lado3 = lado3;
        this.lado4 = lado4;
    }

    @Override
    public double calcularPerimetro() {
        return lado1 + lado2 + lado3 + lado4;
    }
}

Passo 4

Vamos criar a classe Retangulo, que herda de Quadrilatero. Para um retângulo, os lados opostos são iguais, então podemos simplificar o construtor recebendo apenas a base e a altura. Também precisamos implementar o método calcularArea(), que para o retângulo é base vezes altura.
public class Retangulo extends Quadrilatero {
    private double base;
    private double altura;

    public Retangulo(double base, double altura) {
        super(base, altura, base, altura);
        this.base = base;
        this.altura = altura;
    }

    @Override
    public double calcularArea() {
        return base * altura;
    }
}

Passo 5

Agora, vamos criar a classe Quadrado, que também herda de Quadrilatero. No caso do quadrado, todos os lados são iguais, então o construtor recebe apenas o tamanho do lado. O método calcularArea() para o quadrado é lado ao quadrado.
public class Quadrado extends Quadrilatero {
    private double lado;

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

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

Passo 6

Vamos criar a classe Circulo, que implementa a interface FormaGeometrica. Como o círculo não é um quadrilátero, ele não precisa herdar de Quadrilatero. O perímetro do círculo é conhecido como circunferência, que é 2 * π * raio, e a área é π * raio².
public class Circulo implements FormaGeometrica {
    private double raio;

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

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

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

Passo 7

Agora, vamos criar o programa principal onde o usuário vai interagir. Vamos perguntar quantas formas ele quer criar e, para cada uma, que tipo de forma quer (quadrado, retângulo ou círculo). Depois, vamos pedir os dados necessários, criar os objetos e armazená-los em uma lista. Por fim, vamos imprimir os dados, perímetros e áreas de todas as formas.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class ProgramaPrincipal {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        List<FormaGeometrica> formas = new ArrayList<>();

        System.out.print("Quantas formas você deseja criar? ");
        int quantidade = scanner.nextInt();

        for (int i = 0; i < quantidade; i++) {
            System.out.println("Escolha o tipo da forma (1 - Quadrado, 2 - Retângulo, 3 - Círculo): ");
            int escolha = scanner.nextInt();

            switch (escolha) {
                case 1:
                    System.out.print("Digite o tamanho do lado do quadrado: ");
                    double lado = scanner.nextDouble();
                    formas.add(new Quadrado(lado));
                    break;
                case 2:
                    System.out.print("Digite o tamanho da base do retângulo: ");
                    double base = scanner.nextDouble();
                    System.out.print("Digite o tamanho da altura do retângulo: ");
                    double altura = scanner.nextDouble();
                    formas.add(new Retangulo(base, altura));
                    break;
                case 3:
                    System.out.print("Digite o tamanho do raio do círculo: ");
                    double raio = scanner.nextDouble();
                    formas.add(new Circulo(raio));
                    break;
                default:
                    System.out.println("Opção inválida. Tente novamente.");
                    i--; // Repete a iteração para escolher novamente
            }
        }

        System.out.println("\n--- Dados das Formas ---");
        for (FormaGeometrica forma : formas) {
            if (forma instanceof Quadrado) {
                Quadrado q = (Quadrado) forma;
                System.out.println("Quadrado:");
                System.out.println("Lado: " + q.lado);
            } else if (forma instanceof Retangulo) {
                Retangulo r = (Retangulo) forma;
                System.out.println("Retângulo:");
                System.out.println("Base: " + r.base + ", Altura: " + r.altura);
            } else if (forma instanceof Circulo) {
                Circulo c = (Circulo) forma;
                System.out.println("Círculo:");
                System.out.println("Raio: " + c.raio);
            }

            System.out.printf("Perímetro: %.2f%n", forma.calcularPerimetro());
            System.out.printf("Área: %.2f%n%n", forma.calcularArea());
        }

        scanner.close();
    }
}

Resposta

Pronto! Com esses passos, você conseguiu criar uma hierarquia de classes que representa diferentes formas geométricas, permitindo calcular seus perímetros e áreas de forma organizada e eficiente. Agora, ao executar o programa principal, o usuário pode criar quantas formas desejar e visualizar todas as informações solicitadas para cada uma delas.

Exercícios relacionados

Quais são os modificadores de acesso do java
o que é encapsulamento e para que ele serve? Utilize um exemplo simples.
Crie um programa que permita ao usuário inserir uma série de inteiros em um ArrayList, calcular a soma, a média, o valor máximo e o valor mínimo dos números inseridos.
[classe abstrata, herança, sobrescrita, polimorfismo] Crie uma hierarquia de classes para representar os diferentes tipos de funcionários de um escritório que tem os seguintes cargos: gerente, assistente, vendedor. Escreva uma classe base abstrata chamada Funcionario que declara um método abstrato:

public double calculaSalario()

Esta classe também deve definir os seguintes atributos: nome (tipo String), matricula (tipo String) e salario_base (tipo double). Use encapsulamento e forneça um construtor que recebe os valores correspondentes a serem armazenados nos respectivos atributos. Esta classe abstrata deverá ser estendida pelas outras classes representativas dos tipos de funcionários, portanto devem ser escritas as classes Gerente, Assistente e Vendedor. Em cada classe deve-se sobrescrever o método calculaSalario de forma que cálculo do salário é feito assim: O gerente recebe duas vezes o salário_base, o assistente recebe o salário_base e o vendedor
recebe o salário_base mais uma comissão definida no construtor de sua classe. Crie uma classe Teste com um método main que cria um objeto de cada tipo e os armazena em uma lista e depois calcula a folha salarial dos três funcionários e imprime o valor total. Indique quais conceitos de POO você usou e como foi usado.