Fácil Java
Formas geométricas polimórficas
Enunciado
Crie uma hierarquia de classes para representar formas geométricas. A superclasse Forma deve ter um método area() que retorna double. As subclasses Circulo e Retangulo devem implementar area() com as fórmulas corretas. No main, crie um array de Forma com um círculo de raio 2.0 e um retângulo de base 3.0 e altura 4.0. Percorra o array e imprima a área de cada forma.
Requisitos
- A classe
Formadeve ser abstrata ou ter métodoarea()que retorna 0. Circulocalcula área comoMath.PI * raio * raio.Retangulocalcula área comobase * altura.- O programa imprime as áreas com duas casas decimais.
Código inicial
abstract class Forma {
abstract double area();
}
// TODO: crie Circulo e Retangulo
public class Main {
public static void main(String[] args) {
// TODO: crie array de Forma e imprima as áreas
}
}
Saída esperada
Área do círculo: 12,57
Área do retângulo: 12,00
Ver dica
Use String.format("%.2f", valor) para formatar com duas casas decimais. Lembre-se de que o separador decimal pode ser vírgula dependendo do locale, mas o esperado é ponto. Para garantir ponto, use String.format(Locale.US, "%.2f", valor).
Mostrar solução
import java.util.Locale;
abstract class Forma {
abstract double area();
}
class Circulo extends Forma {
private double raio;
Circulo(double raio) {
this.raio = raio;
}
@Override
double area() {
return Math.PI * raio * raio;
}
}
class Retangulo extends Forma {
private double base;
private double altura;
Retangulo(double base, double altura) {
this.base = base;
this.altura = altura;
}
@Override
double area() {
return base * altura;
}
}
public class Main {
public static void main(String[] args) {
Forma[] formas = { new Circulo(2.0), new Retangulo(3.0, 4.0) };
for (Forma f : formas) {
// Despacho dinâmico: area() chama a implementação correta
double area = f.area();
String tipo = (f instanceof Circulo) ? "círculo" : "retângulo";
System.out.printf(Locale.US, "Área do %s: %.2f%n", tipo, area);
}
}
}
Passo a passo
- Definimos a classe abstrata
Formacom o método abstratoarea(). Isso estabelece o contrato que todas as formas devem seguir. CirculoestendeForma, armazena o raio e implementaarea()usandoMath.PI * raio * raio.Retangulotambém estendeForma, armazena base e altura e implementaarea()comobase * altura.- No
main, criamos um array do tipoForma[]contendo umCirculoe umRetangulo. Isso é possível porque ambos são subtipos deForma. - Iteramos sobre o array com um
for-each. A variávelfé do tipoForma, mas o objeto real é de uma subclasse. - Dentro do loop, chamamos
f.area(). O despacho dinâmico garante que a implementação correta seja executada para cada objeto. - Usamos
f instanceof Circulopara determinar o tipo e imprimir a mensagem adequada. Isso não afeta o cálculo da área, que já é polimórfico. - Formatamos a saída com
String.formatusandoLocale.USpara garantir o ponto decimal.
Por que funciona
O polimorfismo permite tratar objetos de diferentes subclasses de forma uniforme através de uma referência de superclasse. O método area() é sobrescrito em cada subclasse, e a JVM decide qual versão chamar com base no tipo real do objeto em tempo de execução. Assim, o mesmo código (f.area()) produz resultados diferentes conforme o objeto.
Erros comuns
- Esquecer de sobrescrever
area(): se a subclasse não implementar o método abstrato, o código não compila. Certifique-se de usar@Override. - Usar
==para comparar tipos:f instanceof Circuloé correto;f.getClass() == Circulo.classtambém funciona, mas é menos idiomático e não lida com subclasses. - Formatação com vírgula: sem
Locale.US,String.format("%.2f", 12.57)pode imprimir12,57em locales que usam vírgula. UseLocale.USpara garantir o ponto.
Outra forma de resolver
Poderia-se usar uma interface Forma em vez de classe abstrata. A escolha depende se há código comum a ser compartilhado. Exemplo:
interface Forma {
double area();
}
Isso é preferível quando não há estado ou comportamento comum.
Saída esperada
Área do círculo: 12.57
Área do retângulo: 12.00