CodeGym /Cursos /JAVA 25 SELF /Sobrecarga de construtores

Sobrecarga de construtores

JAVA 25 SELF
Nível 14 , Lição 4
Disponível

1. Sintaxe da sobrecarga de construtores

Na prática, é raro que todos os objetos sejam criados da mesma maneira. Imagine a classe Person (Pessoa). Às vezes precisamos criar uma pessoa sabendo apenas o nome. Às vezes — nome e idade. E às vezes — não sabemos nada; deixe que tudo fique como padrão. Seria estranho obrigar o usuário da classe a sempre informar todos os parâmetros, mesmo quando ele não precisa deles.

Sobrecarga de construtores é uma forma de dar ao usuário da classe a escolha sobre quais parâmetros deseja informar ao criar o objeto e quais deixar com valores padrão. Isso torna a classe flexível e fácil de usar.

Analogia:
Em um escritório de projetos se constroem automóveis. Alguém pede a configuração básica (sem ar-condicionado, só volante e rodas), alguém quer “luxo” (com aquecimento de bancos, Wi‑Fi e que o carro dirija sozinho). Mas o carro — ainda é a mesma classe; apenas diferentes maneiras de montá-lo!

Sobrecarga é quando em uma mesma classe são declarados vários construtores, mas com parâmetros diferentes (quantidade, tipo ou ordem de parâmetros). Todos têm o mesmo nome da classe e não possuem tipo de retorno.

Exemplo: classe com construtores sobrecarregados

public class Person {
    String name;
    int age;

    // Construtor sem parâmetros (padrão)
    public Person() {
        this.name = "Desconhecido";
        this.age = 0;
    }

    // Construtor com um parâmetro
    public Person(String name) {
        this.name = name;
        this.age = 0;
    }

    // Construtor com dois parâmetros
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Agora podemos criar objetos de maneiras diferentes:

Person p1 = new Person();                // nome = "Desconhecido", idade = 0
Person p2 = new Person("Vasya");         // nome = "Vasya", idade = 0
Person p3 = new Person("Petya", 25);     // nome = "Petya", idade = 25

Como o Java decide qual construtor usar?

O Java observa a quantidade e os tipos dos argumentos que você passa após new. Se você escreve new Person("Vasya"), o compilador busca um construtor com um parâmetro do tipo String. Se você escreve new Person("Petya", 25), é necessário um construtor com parâmetros String e int.

2. Chamando um construtor a partir de outro: this(...)

Às vezes, ao sobrecarregar construtores, surge uma situação em que parte do código se repete. Por exemplo, você quer que todos os construtores definam obrigatoriamente o nome, e que a idade, se não informada, seja zero. Para não copiar a mesma lógica em cada construtor, é possível chamar um construtor a partir de outro com a palavra-chave this(...).

Exemplo

public class Person {
    String name;
    int age;

    // Construtor com dois parâmetros
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Construtor com um parâmetro chama outro construtor
    public Person(String name) {
        this(name, 0); // chama Person(String name, int age)
    }

    // Construtor sem parâmetros chama outro construtor
    public Person() {
        this("Desconhecido", 0);
    }
}
public Person(String name) {
    this(name, 0); // chama Person(String, int)
}
Chamada de um construtor a partir de outro com this(...)

Regra importante: a chamada a outro construtor com this(...) deve ser a primeira linha do construtor!

Por que isso é útil?

  • Reduz a duplicação de código.
  • Se você decidir alterar a lógica de inicialização (por exemplo, mudar um valor padrão), só será necessário alterar em um único lugar.
  • O código fica mais limpo e mais fácil de manter.

3. Exemplos práticos: sobrecarga em uma classe real

Suponha que temos a classe Account — conta bancária. Às vezes sabemos apenas o nome do proprietário, às vezes queremos informar logo o saldo inicial e, em outras, também a moeda.

Exemplo de classe com construtores sobrecarregados

public class Account {
    String owner;
    double balance;
    String currency;

    // Construtor com três parâmetros
    public Account(String owner, double balance, String currency) {
        this.owner = owner;
        this.balance = balance;
        this.currency = currency;
    }

    // Construtor com dois parâmetros (moeda padrão — "EUR")
    public Account(String owner, double balance) {
        this(owner, balance, "EUR");
    }

    // Construtor com um parâmetro (saldo = 0, moeda = "EUR")
    public Account(String owner) {
        this(owner, 0.0, "EUR");
    }

    // Construtor sem parâmetros (proprietário — "Desconhecido", saldo = 0, moeda = "EUR")
    public Account() {
        this("Desconhecido", 0.0, "EUR");
    }

    public void printInfo() {
        System.out.println(owner + ": " + balance + " " + currency);
    }
}

Uso

public class Main {
    public static void main(String[] args) {
        Account acc1 = new Account("Ivan", 1000, "USD");
        Account acc2 = new Account("Mariya", 500);
        Account acc3 = new Account("Pyotr");
        Account acc4 = new Account();

        acc1.printInfo(); // Ivan: 1000.0 USD
        acc2.printInfo(); // Mariya: 500.0 EUR
        acc3.printInfo(); // Pyotr: 0.0 EUR
        acc4.printInfo(); // Desconhecido: 0.0 EUR
    }
}

Por que isso é conveniente?

  • É possível criar objetos com diferentes níveis de detalhamento.
  • Não é necessário informar todos os parâmetros sempre (especialmente se eles costumam ser iguais).
  • É fácil expandir a classe: se surgir um novo parâmetro, é possível adicionar mais um construtor.

4. Erros comuns ao sobrecarregar construtores

Erro nº 1: confusão com tipos e ordem dos parâmetros.
Se você tem dois construtores — Person(String name, int age) e Person(int age, String name) — o compilador vai distingui-los, mas para o usuário da classe isso pode ser extremamente confuso. É melhor evitar tais situações.

Erro nº 2: ausência de construtor padrão.
Se você declarou apenas construtores com parâmetros e, depois, tenta criar um objeto sem parâmetros — ocorrerá um erro de compilação. Sempre adicione um construtor sem parâmetros, se ele for necessário.

Erro nº 3: tentar chamar outro construtor não na primeira linha.
A chamada this(...) deve sempre ser a primeira linha do construtor. Se houver algo antes disso — haverá erro de compilação.

Erro nº 4: encadeamento cíclico de chamadas de construtores.
Se um construtor chama a si mesmo (diretamente ou por meio de uma cadeia), isso levará a um erro de compilação devido a recursão infinita.

Erro nº 5: campos não inicializados.
Se você esquecer de inicializar algum campo no construtor (ou na cadeia de chamadas), o objeto pode acabar em um estado incorreto. Verifique se todos os campos têm valores significativos após a criação do objeto.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION