Atualizado: 09/08/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Hierarquia de Herança e Conversão de Tipos em Java

Em Java, a conversão de tipos para objetos segue regras diferentes das aplicadas a tipos primitivos, pois está diretamente ligada à hierarquia de classes.

Exemplo de hierarquia

public class Program {
    public static void main(String[] args) {

        Person tom = new Person("Tom");
        tom.display();

        Person sam = new Employee("Sam", "Oracle");
        sam.display();

        Person bob = new Client("Bob", "DeutscheBank", 3000);
        bob.display();
    }
}

// Classe que representa uma pessoa
class Person {

    private String name;

    public String getName() {
        return name;
    }

    public Person(String name) {
        this.name = name;
    }

    public void display() {
        System.out.printf("Person %s%n", name);
    }
}

// Funcionário de uma empresa
class Employee extends Person {

    private String company;

    public Employee(String name, String company) {
        super(name);
        this.company = company;
    }

    public String getCompany() {
        return company;
    }

    @Override
    public void display() {
        System.out.printf("Employee %s works in %s%n", getName(), company);
    }
}

// Cliente de um banco
class Client extends Person {

    private int sum;  // saldo da conta
    private String bank;

    public Client(String name, String bank, int sum) {
        super(name);
        this.bank = bank;
        this.sum = sum;
    }

    @Override
    public void display() {
        System.out.printf("Client %s has account in %s%n", getName(), bank);
    }

    public String getBank() {
        return bank;
    }

    public int getSum() {
        return sum;
    }
}

Essa hierarquia pode ser representada como:

Object → Person → Employee | Client

Hierarquia de Classes

Todas as classes em Java herdam implicitamente de Object, que fica no topo da hierarquia.


Upcasting (conversão ascendente)

Um objeto de uma subclasse também é um objeto da sua superclasse. Isso permite, por exemplo:

Object tom = new Person("Tom");
Object sam = new Employee("Sam", "Oracle");
Object kate = new Client("Kate", "DeutscheBank", 2000);

Person bob = new Client("Bob", "DeutscheBank", 3000);
Person alice = new Employee("Alice", "Google");

O upcasting é a conversão do tipo mais específico (subclasse) para um tipo mais genérico (superclasse). Essa conversão é automática e segura.


Downcasting (conversão descendente)

A conversão inversa — de superclasse para subclasse — é chamada de downcasting. Nem todo objeto do tipo Person é necessariamente um Employee ou Client. Por isso, o downcasting precisa ser feito de forma explícita.

Object sam = new Employee("Sam", "Oracle");

// Conversão explícita de Object para Employee
Employee emp = (Employee) sam;
emp.display();
System.out.println(emp.getCompany());

Essa conversão é válida porque sam realmente armazena um Employee.

Também é possível converter usando toda a cadeia de herança:

Object kate = new Client("Kate", "DeutscheBank", 2000);
((Person) kate).display();

Object sam = new Employee("Sam", "Oracle");
((Employee) sam).display();

Erro de downcasting

O problema ocorre quando o objeto real não é do tipo esperado:

Object kate = new Client("Kate", "DeutscheBank", 2000);

// Compila, mas gera ClassCastException em tempo de execução
Employee emp = (Employee) kate;
emp.display();

Nesse exemplo, kate é um Client. Converter para Person ou Client funciona, mas para Employee resulta em erro de execução, pois kate não é um Employee.


Prevenindo erros com instanceof

Para evitar problemas, é possível verificar o tipo real do objeto antes da conversão:

Object kate = new Client("Kate", "DeutscheBank", 2000);

if (kate instanceof Employee) {
    Employee employeeKate = (Employee) kate;
    employeeKate.display();
} else {
    System.out.println("Conversion is invalid");
}

O operador instanceof retorna true se o objeto for de um tipo específico (ou de um subtipo). No exemplo, kate instanceof Employee retorna false, enquanto kate instanceof Client retornaria true.


Pattern Matching com instanceof

É possível simplificar o código usando pattern matching com instanceof:

Object kate = new Client("Kate", "DeutscheBank", 2000);

if (kate instanceof Client clientKate) {
    clientKate.display();
} else {
    System.out.println("Conversion is invalid");
}

Aqui, a expressão:

kate instanceof Client clientKate

Verifica se kate é um Client. Se for, cria automaticamente a variável clientKate já convertida, evitando um casting manual separado.


📝 Exercícios

Tarefa 1 — Identificar tipo real do objeto

Descrição: Dada a hierarquia Person → Employee e Person → Client, explique o resultado da expressão:

Object obj = new Client("Ana", "Itau", 2000);
boolean result = obj instanceof Employee;
Resposta

Resposta: O valor de result será false, pois o objeto real é Client, não Employee.

Explicação: O operador instanceof verifica o tipo real do objeto, não apenas o tipo da variável.


Tarefa 2 — Diferença entre upcasting e downcasting

Descrição: Explique a principal diferença entre upcasting e downcasting em Java e qual deles é seguro sem verificação prévia.

Resposta

Resposta:

  • Upcasting: conversão de subclasse para superclasse, é automática e sempre segura.
  • Downcasting: conversão de superclasse para subclasse, exige casting explícito e pode causar erro em tempo de execução.
  • Política de Privacidade

    Copyright © www.programicio.com Todos os direitos reservados

    É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

    Contato: programicio@gmail.com