Construtores
🏗️ Construtores em Java: O Guia Completo para Iniciantes
Olá, futuro desenvolvedor Java! Hoje vamos mergulhar em um dos conceitos mais importantes da programação orientada a objetos: os construtores. Pense neles como a "certidão de nascimento" dos seus objetos - é o momento em que eles ganham vida!
🤔 O que é um Construtor?
Um construtor é um método especial que é chamado automaticamente quando você cria um novo objeto usando a palavra-chave new. Sua principal função é inicializar o objeto, definindo valores iniciais para seus atributos.
Características principais:
- Tem o mesmo nome da classe
- Não tem tipo de retorno (nem
void!) - É chamado automaticamente na criação do objeto
public class Carro {
String modelo;
int ano;
// Este é um construtor!
public Carro() {
System.out.println("Um novo carro foi criado!");
}
}
// Uso:
Carro meuCarro = new Carro(); // Aqui o construtor é chamado
🎯 Construtor Padrão (Sem Parâmetros)
Se você não criar nenhum construtor, o Java fornece um construtor padrão (default constructor) automaticamente. Ele não faz nada além de criar o objeto.
public class Pessoa {
String nome;
int idade;
// Construtor padrão é criado automaticamente pelo Java
// É como se tivesse: public Pessoa() {}
}
public class Teste {
public static void main(String[] args) {
Pessoa p = new Pessoa(); // Funciona perfeitamente!
System.out.println(p.nome); // null
System.out.println(p.idade); // 0
}
}
⚠️ Atenção! Se você criar QUALQUER construtor, o Java não fornece mais o construtor padrão!
🎨 Construtor Parametrizado
É um construtor que recebe parâmetros para inicializar os atributos com valores específicos.
public class Aluno {
String nome;
int matricula;
double nota;
// Construtor parametrizado
public Aluno(String nome, int matricula, double nota) {
this.nome = nome;
this.matricula = matricula;
this.nota = nota;
}
}
public class Teste {
public static void main(String[] args) {
Aluno aluno1 = new Aluno("Maria", 12345, 9.5);
Aluno aluno2 = new Aluno("João", 12346, 7.8);
}
}
🔄 this() - Chamando Outro Construtor
A palavra-chave this() permite que um construtor chame outro construtor da mesma classe. Isso evita duplicação de código!
public class ContaBancaria {
String titular;
double saldo;
String tipo;
// Construtor mais completo
public ContaBancaria(String titular, double saldo, String tipo) {
this.titular = titular;
this.saldo = saldo;
this.tipo = tipo;
System.out.println("Conta " + tipo + " criada para " + titular);
}
// Construtor simplificado - chama o construtor acima!
public ContaBancaria(String titular) {
this(titular, 0.0, "Corrente"); // this() DEVE ser a primeira linha!
}
}
public class Teste {
public static void main(String[] args) {
ContaBancaria c1 = new ContaBancaria("Ana", 1000.0, "Poupança");
ContaBancaria c2 = new ContaBancaria("Carlos"); // Saldo 0, tipo Corrente
}
}
📚 Múltiplos Construtores (Sobrecarga)
Você pode ter vários construtores na mesma classe, desde que tenham parâmetros diferentes. Isso se chama sobrecarga de construtores.
public class Produto {
String nome;
double preco;
int quantidade;
// Construtor 1: apenas nome
public Produto(String nome) {
this(nome, 0.0, 0); // Chama o construtor 3
}
// Construtor 2: nome e preço
public Produto(String nome, double preco) {
this(nome, preco, 0); // Chama o construtor 3
}
// Construtor 3: todos os atributos
public Produto(String nome, double preco, int quantidade) {
this.nome = nome;
this.preco = preco;
this.quantidade = quantidade;
}
}
public class Teste {
public static void main(String[] args) {
Produto p1 = new Produto("Arroz");
Produto p2 = new Produto("Feijão", 8.50);
Produto p3 = new Produto("Macarrão", 4.99, 10);
}
}
⚖️ Construtor vs Setter: Quando Usar Cada Um?
Use construtor quando:
- O atributo é obrigatório para o objeto existir
- O valor não vai mudar durante a vida do objeto
- Você quer garantir que o objeto já nasça "completo"
Use setter quando:
- O atributo é opcional ou tem valor padrão
- O valor pode mudar depois
- Você precisa de validação complexa
public class Usuario {
// Atributos obrigatórios - vão no construtor
private String email;
private String senha;
// Atributos opcionais - podem ter setters
private String nome;
private int idade;
public Usuario(String email, String senha) {
this.email = email;
this.senha = senha;
}
// Setters para atributos opcionais
public void setNome(String nome) {
this.nome = nome;
}
public void setIdade(int idade) {
if (idade > 0) {
this.idade = idade;
}
}
}
💻 Exemplo Prático: Classe Produto Completa
Vamos criar uma classe Produto profissional com construtores bem pensados:
public class Produto {
// Atributos
private String nome;
private double preco;
private int quantidade;
private String codigo;
// Construtor completo
public Produto(String nome, double preco, int quantidade, String codigo) {
this.nome = nome;
this.preco = preco;
this.quantidade = quantidade;
this.codigo = codigo;
}
// Construtor para produtos sem código ainda
public Produto(String nome, double preco, int quantidade) {
this(nome, preco, quantidade, "PENDENTE");
}
// Construtor para produtos sem quantidade (estoque inicial 0)
public Produto(String nome, double preco) {
this(nome, preco, 0, "PENDENTE");
}
// Construtor mínimo - apenas nome (preço 0, sem estoque)
public Produto(String nome) {
this(nome, 0.0, 0, "PENDENTE");
}
// Getters e Setters
public String getNome() { return nome; }
public void setNome(String nome) { this.nome = nome; }
public double getPreco() { return preco; }
public void setPreco(double preco) {
if (preco >= 0) {
this.preco = preco;
}
}
public int getQuantidade() { return quantidade; }
public void setQuantidade(int quantidade) {
if (quantidade >= 0) {
this.quantidade = quantidade;
}
}
public String getCodigo() { return codigo; }
// Método para exibir informações
public void exibirInfo() {
System.out.println("Produto: " + nome);
System.out.println("Preço: R$" + preco);
System.out.println("Quantidade: " + quantidade);
System.out.println("Código: " + codigo);
}
}
public class Teste {
public static void main(String[] args) {
Produto p1 = new Produto("Notebook", 3500.0, 5, "NTB-001");
Produto p2 = new Produto("Mouse", 50.0, 10);
Produto p3 = new Produto("Teclado", 120.0);
Produto p4 = new Produto("Monitor");
p1.exibirInfo();
System.out.println("---");
p4.exibirInfo();
}
}
🚨 Erros Comuns (e Como Evitá-los)
❌ Erro 1: Colocar tipo de retorno no construtor
public class Erro {
// ERRADO! Construtor não pode ter void
public void Erro() {
System.out.println("Isso não é um construtor!");
}
// CERTO
public Erro() {
System.out.println("Isso é um construtor!");
}
}
❌ Erro 2: Nome do construtor diferente da classe
public class Animal {
// ERRADO! Nome diferente da classe
public Animal() { } // CORRETO
// public animal() { } // ERRADO!
}
❌ Erro 3: Esquecer de criar construtor padrão
public class Exemplo {
private int valor;
// Se você criar este construtor...
public Exemplo(int valor) {
this.valor = valor;
}
public static void main(String[] args) {
// ... este código NÃO funciona!
// Exemplo e = new Exemplo(); // ERRO DE COMPILAÇÃO!
// Precisa fazer assim:
Exemplo e = new Exemplo(10); // OK
}
}
❌ Erro 4: this() não ser a primeira linha
public class ErroThis {
private int a;
private int b;
public ErroThis(int a, int b) {
this.a = a;
this.b = b;
}
public ErroThis(int a) {
System.out.println("Teste"); // ERRADO! this() deve ser a primeira linha
this(a, 0); // Isso causaria erro de compilação
}
}
💡 Dicas Finais
- Sempre valide parâmetros no construtor (preços negativos, etc.)
- Use this() para evitar repetir código entre construtores
- Prefira construtores para atributos que nunca mudam
- Documente seus construtores com comentários claros
- Considere o padrão Builder para classes com muitos atributos
Parabéns! Agora você entende como os construtores funcionam em Java. Pratique criando suas próprias classes com diferentes tipos de construtores. Lembre-se: um bom construtor é a base para objetos bem construídos! 🚀