Encadeamento de Construtores
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 23 de 87.
Encadeamento de construtores é o processo de chamar um construtor a partir de outro. Esta técnica ajuda a evitar a duplicação de código quando uma classe possui múltiplos construtores ou ao trabalhar com hierarquias de herança.
Dentro da mesma classe, você pode encadear construtores usando this(). Isso permite que você tenha um construtor "principal" que faz todo o trabalho, enquanto outros construtores simplesmente delegam para ele:
public class Rectangle {
private int width;
private int height;
public Rectangle() {
this(1, 1); // Chama o construtor de dois parâmetros
}
public Rectangle(int size) {
this(size, size); // Cria um quadrado
}
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
}Na herança, o encadeamento de construtores acontece automaticamente. Quando você cria um objeto de uma subclasse, o Java chama o construtor pai primeiro usando super(). Se você não chamar explicitamente super(), o Java insere super() (a versão sem argumentos) automaticamente:
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal constructor");
}
}
public class Dog extends Animal {
private String breed;
public Dog(String name, String breed) {
super(name); // Deve ser a primeira linha
this.breed = breed;
System.out.println("Dog constructor");
}
}A criação de new Dog("Buddy", "Labrador") imprime "Animal constructor" primeiro, depois "Dog constructor". Isso garante que as classes pai sejam sempre inicializadas corretamente antes que a classe filha adicione sua própria configuração.
Desafio
FácilVamos construir um sistema de pedidos de produtos que demonstra o encadeamento de construtores tanto dentro de uma classe quanto em uma hierarquia de herança. Você verá como this() encadeia construtores na mesma classe, enquanto super() encadeia para construtores pai.
Você criará três arquivos para organizar seu código:
Product.java: Crie uma classe pai representando qualquer produto em uma loja. Ela deve ter:- Campos privados para
name(String) eprice(double) - Um construtor principal que recebe tanto o nome quanto o preço, inicializa os campos e imprime:
Product constructor: [name] - Um segundo construtor que recebe apenas o nome e encadeia para o construtor principal usando
this(name, 0.0)para definir um preço padrão de 0.0 - Métodos
getName()egetPrice()para acessar os campos
- Campos privados para
Electronics.java: Crie uma subclasse que estende Product e adiciona informações de garantia:- Um campo privado para
warrantyYears(int) - Um construtor principal que recebe name, price e warrantyYears - use
super(name, price)para inicializar o pai, depois defina a garantia e imprima:Electronics constructor: [warrantyYears] year warranty - Um segundo construtor que recebe apenas name e price, encadeando para o construtor principal com
this(name, price, 1)para fornecer uma garantia padrão de 1 ano - Um terceiro construtor que recebe apenas o nome, encadeando para o segundo construtor com
this(name, 0.0) - Um método
getDetails()que retorna:[name] - $[price] ([warrantyYears] year warranty)
- Um campo privado para
Main.java: Demonstre o encadeamento de construtores em ação. Você receberá três entradas: um nome de produto (String), preço (double) e anos de garantia (int). Crie um objeto Electronics usando todos os três parâmetros e, em seguida, imprima o resultado degetDetails().
Você receberá três entradas: o nome do produto, o preço e os anos de garantia.
Formate o preço em getDetails() para mostrar 2 casas decimais usando String.format("%.2f", price). Observe a saída com atenção - você verá as mensagens do construtor aparecerem em ordem, mostrando como a cadeia flui do pai para o filho!
Folha de consulta
O encadeamento de construtores (constructor chaining) é o processo de chamar um construtor a partir de outro para evitar a duplicação de código.
Encadeamento Dentro da Mesma Classe
Use this() para chamar outro construtor na mesma classe:
public class Rectangle {
private int width;
private int height;
public Rectangle() {
this(1, 1); // Chama o construtor de dois parâmetros
}
public Rectangle(int size) {
this(size, size); // Cria um quadrado
}
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
}Encadeamento na Herança
Use super() para chamar o construtor da classe pai. Ele deve ser a primeira linha no construtor:
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
System.out.println("Animal constructor");
}
}
public class Dog extends Animal {
private String breed;
public Dog(String name, String breed) {
super(name); // Deve ser a primeira linha
this.breed = breed;
System.out.println("Dog constructor");
}
}Se você não chamar explicitamente super(), o Java insere automaticamente super() (a versão sem argumentos). Os construtores pai são sempre chamados antes dos construtores filhos, garantindo a ordem correta de inicialização.
Experimente você mesmo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ler entradas
String name = scanner.nextLine();
double price = scanner.nextDouble();
int warrantyYears = scanner.nextInt();
// TODO: Criar um objeto Electronics usando todos os três parâmetros
// TODO: Imprimir o resultado de getDetails()
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Iterator