Palavra‑chave super do Java explicada: construtores, métodos e campos (com exemplos)

目次

1. Relação Entre Herança e super

Para entender a palavra-chave super do Java, você deve primeiro entender herança.
super não é algo que você memoriza isoladamente — seu significado fica claro quando você vê como uma classe filha e uma classe pai trabalham juntas.

Nesta seção, você aprenderá o que é herança e por que super existe em primeiro lugar, usando explicações amigáveis para iniciantes e exemplos de código simples.

1.1 O Que É Herança no Java? (Básicos de extends)

No Java, herança permite que você crie uma nova classe baseada em uma classe existente.

  • Classe pai (superclasse) : a classe base
  • Classe filha (subclasse) : a classe que herda da classe pai

Quando uma classe filha estende uma classe pai, ela pode reutilizar os campos e métodos do pai sem reescrevê-los.

Sintaxe básica de herança (extends)

class Parent {
    void hello() {
        System.out.println("Hello from Parent");
    }
}

class Child extends Parent {
}

Aqui, Child herda o método hello() de Parent.

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.hello(); // calling a method inherited from Parent
    }
}

Saída:

Hello from Parent

Então, mesmo que Child não defina hello(), ela ainda pode chamá-lo porque o herdou.

1.2 Por Que Precisamos de super?

Nesse ponto, você pode pensar:

“Se a filha já herda tudo do pai, por que precisamos de super afinal?”

Em muitos casos, você não precisa escrever super explicitamente.
No entanto, super se torna necessário quando você quer acessar claramente a versão do pai de algo.

Situações comuns incluem:

  • A classe filha sobrescreve um método, mas você ainda quer chamar a versão do pai
  • A classe filha e a classe pai têm campos com o mesmo nome
  • Você precisa chamar um construtor específico do pai usando argumentos

Em resumo:

super é usado quando você quer se referir explicitamente ao lado da classe pai.

1.3 Sobrescrita e super (Mantendo o Comportamento do Pai)

Uma das razões mais comuns para usar super é sobrescrita de método.

Sobrescrever significa que a classe filha fornece sua própria versão de um método que já existe na classe pai.

Exemplo: sobrescrevendo um método

class Parent {
    void greet() {
        System.out.println("Parent: Hello!");
    }
}

class Child extends Parent {
    @Override
    void greet() {
        System.out.println("Child: Hi!");
    }
}

Agora, se você chamar greet() em um objeto Child:

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.greet();
    }
}

Saída:

Child: Hi!

A versão da filha executa, porque a sobrescrita dá prioridade à classe filha.

Chamando a versão do pai com super.greet()

Às vezes, você não quer substituir completamente o comportamento do pai — você só quer adicionar lógica extra.

É aí que super.method() é útil:

class Parent {
    void greet() {
        System.out.println("Parent: Hello!");
    }
}

class Child extends Parent {
    @Override
    void greet() {
        super.greet(); // call parent version
        System.out.println("Child: Hi!");
    }
}

Saída:

Parent: Hello!
Child: Hi!

Este é um padrão muito prático:

  • Classe pai lida com comportamento comum
  • Classe filha adiciona comportamento personalizado

1.4 Quando Pai e Filha Têm o Mesmo Nome de Campo

Outra situação em que super importa é quando uma classe pai e filha têm campos com o mesmo nome.

Exemplo:

class Parent {
    int value = 100;
}

class Child extends Parent {
    int value = 200;

    void printValue() {
        System.out.println(value);
    }
}

Aqui, value se refere ao campo da classe filha, então a saída será:

200

answer.Se você quiser acessar o campo pai, use super.value:

class Child extends Parent {
    int value = 200;

    void printValue() {
        System.out.println(value);       // child value
        System.out.println(super.value); // parent value
    }
}

Saída:

200
100

Ponto principal:

  • value → campo da classe filha
  • super.value → campo da classe pai

1.5 O que super realmente significa (Definição simples)

Agora você pode resumir super assim:

super é uma palavra‑chave que permite acessar explicitamente a versão da classe pai de campos, métodos e construtores.

Se você lembrar de apenas uma linha, lembre‑se disto:

super significa “use a versão da classe pai.”

Na próxima seção, você aprenderá as 3 maneiras mais importantes de usar super, com exemplos claros para cada uma.

2. Como usar super (3 padrões principais)

Agora que você entende o que super significa, vamos focar em como ele é realmente usado em Java.

No código real, super aparece em três padrões principais:

  1. Chamando um construtor pai ( super() / super(args...) )
  2. Chamando um método pai ( super.method() )
  3. Acessando um campo pai ( super.field )

Depois de aprender esses três, super se torna muito fácil de reconhecer e usar corretamente.

2.1 Chamando um Construtor Pai (super() / super(args...))

2.1.1 Revisão rápida: O que é um construtor?

Um construtor é um método especial que é executado quando você cria um objeto.

class Person {
    Person() {
        System.out.println("Person constructor");
    }
}

Construtores são usados para inicialização, como configurar campos.

2.1.2 Na herança, o construtor pai executa primeiro

Na herança Java, criar um objeto filho sempre começa inicializando a parte pai primeiro.

Isso significa:

Construtor pai → Construtor filho

Exemplo:

class Parent {
    Parent() {
        System.out.println("Parent constructor");
    }
}

class Child extends Parent {
    Child() {
        System.out.println("Child constructor");
    }
}

public class Main {
    public static void main(String[] args) {
        new Child();
    }
}

Saída:

Parent constructor
Child constructor

Mesmo que não tenhamos escrito super(), o construtor pai ainda foi executado.

2.1.3 super() é inserido automaticamente (quando possível)

Se a classe pai tem um construtor sem argumentos, Java insere automaticamente esta linha no início do construtor da classe filha:

super();

Então esses dois construtores são efetivamente os mesmos:

Child() {
    System.out.println("Child constructor");
}
Child() {
    super(); // implicitly inserted by the compiler
    System.out.println("Child constructor");
}

2.1.4 Quando a classe pai tem apenas um construtor parametrizado

Este é um dos erros mais comuns entre iniciantes.

Se a classe pai não tem um construtor sem argumentos, Java não pode inserir super() automaticamente.

Exemplo (isto causará um erro de compilação):

class Parent {
    Parent(int x) {
        System.out.println("Parent: " + x);
    }
}

class Child extends Parent {
    Child() {
        System.out.println("Child created");
    }
}

Por que falha:

  • O compilador tenta inserir super();
  • Mas Parent() não existe

✅ Correção: chame explicitamente o construtor pai correto

class Child extends Parent {
    Child() {
        super(10);
        System.out.println("Child created");
    }
}

Saída:

Parent: 10
Child created

2.1.5 super(...) deve ser a primeira linha no construtor

Java requer que super(...) seja a primeira instrução em um construtor.

❌ Errado:

Child() {
    System.out.println("Something first");
    super(10); // compile error
}

✅ Correto:

Child() {
    super(10);
    System.out.println("Child logic");
}

Razão:

  • A classe pai deve ser inicializada antes que a classe filha possa executar com segurança sua própria lógica.

2.2 Chamando um Método da Classe Pai (super.method())

Outro caso de uso muito comum é chamar o método da classe pai após sobrescrevê-lo.

2.2.1 Exemplo básico

class Parent {
    void show() {
        System.out.println("Parent show()");
    }
}

class Child extends Parent {
    @Override
    void show() {
        System.out.println("Child show()");
    }

    void test() {
        super.show(); // parent version
        show();       // child version
    }
}

public class Main {
    public static void main(String[] args) {
        new Child().test();
    }
}

Saída:

Parent show()
Child show()

2.2.2 Quando isso é útil?

super.method() é útil quando:

  • O método da classe pai contém lógica comum
  • O método da classe filha precisa estender o comportamento em vez de substituí-lo
  • Você quer evitar copiar e colar a lógica da classe pai na classe filha

Exemplo:

class Parent {
    void process() {
        System.out.println("Common processing");
    }
}

class Child extends Parent {
    @Override
    void process() {
        super.process();
        System.out.println("Child-specific processing");
    }
}

Esse padrão mantém seu código limpo e manutenível.

2.3 Acessando um Campo da Classe Pai (super.field)

Os campos funcionam de forma semelhante. Se tanto a classe pai quanto a classe filha tiverem um campo com o mesmo nome, o campo da classe filha oculta o campo da classe pai.

Exemplo:

class Parent {
    int value = 100;
}

class Child extends Parent {
    int value = 200;

    void print() {
        System.out.println(value);       // child field
        System.out.println(super.value); // parent field
    }
}

public class Main {
    public static void main(String[] args) {
        new Child().print();
    }
}

Saída:

200
100

2.3.1 Você deve fazer isso em projetos reais?

Normalmente, ter o mesmo nome de campo na classe pai e na classe filha não é uma boa ideia, porque pode confundir os leitores.

No entanto, isso pode acontecer quando:

  • Você está mantendo código legado
  • Você é forçado a corresponder a um design de classe pai existente
  • Você precisa diferenciar claramente os valores da classe pai versus classe filha

Nesses casos, super.field é a ferramenta correta.

2.4 Resumo dos 3 padrões

Você pode lembrar de super assim:

  • super() / super(args...) → chama o construtor da classe pai
  • super.method() → chama o método da classe pai
  • super.field → acessa o campo da classe pai

Na próxima seção, vamos aprofundar com exemplos de código práticos para que você possa ver claramente como esses padrões se comportam quando executados.

3. Exemplos Práticos para Dominar super

Neste ponto, você já conhece as três formas principais de usar super.
Agora, vamos fazer esse conhecimento fixar executando exemplos práticos.

Esta seção foca em:

  • Ordem de execução
  • O que é chamado e por quê
  • Como super altera o comportamento no código real

3.1 Exemplo 1: Ordem de chamada do construtor (Pai → Filho)

A regra mais importante para lembrar:

Ao criar um objeto filho, o Java sempre inicializa a parte pai primeiro.

class Parent {
    Parent() {
        System.out.println("Parent constructor");
    }
}

class Child extends Parent {
    Child() {
        super(); // optional here, but allowed
        System.out.println("Child constructor");
    }
}

public class Main {
    public static void main(String[] args) {
        new Child();
    }
}

Saída:

Parent constructor
Child constructor

Ponto chave:
Mesmo se você remover super(), o resultado é o mesmo (contanto que a classe pai tenha um construtor sem argumentos).

3.2 Exemplo 2: A classe pai tem apenas um construtor parametrizado

Se a classe pai não tiver um construtor sem argumentos, a classe filha deve chamar explicitamente o correto.

class Parent {
    Parent(String name) {
        System.out.println("Parent: " + name);
    }
}

class Child extends Parent {
    Child() {
        super("Taro");
        System.out.println("Child criado");
    }
}

public class Main {
    public static void main(String[] args) {
        new Child();
    }
}

Output:

Parent: Taro
Child criado

Key point:
If you forget super("Taro"), Java tries to insert super() automatically and fails.

3.3 Example 3: Calling a parent method after overriding (super.method())

This is one of the most useful patterns in real projects.

class Parent {
    void greet() {
        System.out.println("Olá do Parent");
    }
}

class Child extends Parent {
    @Override
    void greet() {
        super.greet(); // chamar comportamento do pai
        System.out.println("Olá do Child");
    }
}

public class Main {
    public static void main(String[] args) {
        new Child().greet();
    }
}

Output:

Olá do Parent
Olá do Child

Key point:
You can extend parent behavior without rewriting it.

3.4 Example 4: Accessing a hidden parent field (super.field)

If parent and child both define a field with the same name, the child version hides the parent version.

class Parent {
    int value = 100;
}

class Child extends Parent {
    int value = 200;

    void printValues() {
        System.out.println("Valor do Child: " + value);
        System.out.println("Valor do Parent: " + super.value);
    }
}

public class Main {
    public static void main(String[] args) {
        new Child().printValues();
    }
}

Output:

Valor do Child: 200
Valor do Parent: 100

Key point:

  • value refers to the child’s field
  • super.value refers to the parent’s field

3.5 Example 5: Calling both parent and child versions clearly

This is a great example to remove confusion.

class Parent {
    void show() {
        System.out.println("Parent show()");
    }
}

class Child extends Parent {
    @Override
    void show() {
        System.out.println("Child show()");
    }

    void test() {
        super.show(); // versão do pai
        this.show();  // versão do filho (mesmo que chamar apenas show())
    }
}

public class Main {
    public static void main(String[] args) {
        new Child().test();
    }
}

Output:

Parent show()
Child show()

Key point:

  • super.show() = parent
  • this.show() = child

3.6 A realistic example: shared logic in the parent class

In real applications, parent classes often contain common logic such as logging, validation, or setup steps.

class BaseService {
    void execute() {
        System.out.println("[LOG] Iniciando execução");
    }
}

class UserService extends BaseService {
    @Override
    void execute() {
        super.execute(); // reutilizar comportamento compartilhado
        System.out.println("Lógica do UserService em execução...");
    }
}

public class Main {
    public static void main(String[] args) {
        new UserService().execute();
    }
}

Output:

[LOG] Iniciando execução
Lógica do UserService em execução...

Why this is useful:

  • You avoid duplicating common behavior
  • The child focuses only on what’s unique
  • Your code becomes easier to maintain

3.7 Section summary

From these examples, you should remember:

  • Parent constructors run before child constructors
  • super(args...) is required if the parent has no no-arg constructor
  • super.method() is perfect for reusing and extending behavior
  • super.field helps when parent and child fields share the same name

Next, we’ll clarify one of the most confusing topics for beginners:

What’s the difference between this and super?

4. Difference Between this and super

When learning Java’s super, you will almost always see this at the same time.
Both are reference keywords, so it’s easy for beginners to mix them up.

In this section, you’ll learn:

  • O que this significa
  • O que super significa
  • Como usá-los corretamente com campos, métodos e construtores

4.1 this refere-se ao objeto atual (a instância filha)

this significa:

“a instância atual do objeto”

É mais comumente usado quando o nome de um campo e o nome de um parâmetro do construtor são iguais.

class User {
    String name;

    User(String name) {
        this.name = name; // field = parameter
    }
}

Aqui:

  • name (lado direito) é o parâmetro do construtor
  • this.name (lado esquerdo) é o campo da instância

Então this ajuda a evitar confusão.

4.2 super refere-se ao lado da classe pai

super refere-se à parte da classe pai (superclasse) do objeto atual.

Significa:

“usar a versão da classe pai”

Você o usa principalmente quando deseja acessar membros da classe pai que estão ocultos ou sobrescritos.

4.3 A maneira mais simples de lembrar a diferença

Uma forma amigável para iniciantes memorizar:

  • thiso lado da classe filha
  • supero lado da classe pai

Eles não são dois objetos diferentes.
Eles são duas “visões” diferentes do mesmo objeto.

4.4 Usando this e super com campos

Se tanto a classe pai quanto a filha definirem um campo com o mesmo nome, você pode escolher claramente qual deseja.

class Parent {
    int value = 100;
}

class Child extends Parent {
    int value = 200;

    void print() {
        System.out.println(this.value);  // child field
        System.out.println(super.value); // parent field
    }
}

public class Main {
    public static void main(String[] args) {
        new Child().print();
    }
}

Saída:

200
100

Ponto chave:

  • this.value = campo da filha
  • super.value = campo da pai

Além disso, em Java, this costuma ser opcional:

System.out.println(value);

é o mesmo que:

System.out.println(this.value);

4.5 Usando this e super com métodos

Métodos são a área mais comum onde a diferença entre this e super importa — especialmente com sobrescrita.

class Parent {
    void show() {
        System.out.println("Parent show()");
    }
}

class Child extends Parent {
    @Override
    void show() {
        System.out.println("Child show()");
    }

    void test() {
        this.show();   // child method (same as show())
        super.show();  // parent method
    }
}

public class Main {
    public static void main(String[] args) {
        new Child().test();
    }
}

Saída:

Child show()
Parent show()

Ponto chave:

  • this.show() → versão da filha
  • super.show() → versão da pai

4.6 Construtores: this() vs super()

Esta é uma das partes mais confusas para iniciantes, mas é muito importante.

  • this() chama outro construtor na mesma classe
  • super() chama um construtor na classe pai

4.6.1 Exemplo de this() (encadeamento de construtor dentro da mesma classe)

class User {
    String name;
    int age;

    User() {
        this("NoName", 0); // call another constructor
    }

    User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Isso é útil porque evita repetir a lógica de inicialização.

4.6.2 Exemplo de super() (chamando o construtor da classe pai)

class Parent {
    Parent() {
        System.out.println("Parent constructor");
    }
}

class Child extends Parent {
    Child() {
        super(); // initialize parent
        System.out.println("Child constructor");
    }
}

Saída:

Parent constructor
Child constructor

4.7 Você não pode usar this() e super() juntos

Muitos iniciantes tentam algo assim:

Child() {
    this(1);
    super(); // error
}

Isso não é permitido.

Razão:

  • Tanto this() quanto super() devem ser a primeira linha no construtor
  • Apenas um deles pode ser o primeiro

Portanto, você deve escolher um.

4.8 Lembrete importante: super não cria um novo objeto

.super não cria um objeto pai separado.

Em vez disso:

  • this = objeto atual visto como filho
  • super = mesmo objeto visto como pai

É por isso que super deve ser pensado como uma palavra‑chave de referência, não como um criador de objetos.

4.9 Resumo da seção

  • this refere‑se ao objeto atual (lado filho)
  • super refere‑se ao lado da classe pai
  • this() chama outro construtor na mesma classe
  • super() chama um construtor na classe pai
  • this() e super() não podem ser usados juntos

Em seguida, abordaremos erros comuns e padrões de falha para que você evite as armadilhas mais frequentes para iniciantes.

5. Erros Comuns e Armadilhas (Como Evitar Erros)

A palavra‑chave super do Java é poderosa, mas também é fácil de usar incorretamente — especialmente quando você ainda está aprendendo herança e construtores.

Nesta seção, você aprenderá os erros mais comuns que iniciantes cometem e como corrigi‑los rapidamente.

5.1 Escrever super(...) no lugar errado (regra do construtor)

Uma das regras mais importantes:

super(...) deve ser a primeira instrução dentro de um construtor.

❌ Errado (erro de compilação):

class Parent {
    Parent(int x) {}
}

class Child extends Parent {
    Child() {
        System.out.println("Do something first");
        super(10); // ERROR: must be first line
    }
}

✅ Correto:

class Child extends Parent {
    Child() {
        super(10);
        System.out.println("Child logic");
    }
}

Por quê?
Porque a parte pai do objeto deve ser inicializada antes que a lógica do filho seja executada.

5.2 Esquecer super(args...) quando o pai não tem construtor sem argumentos

Se a classe pai possui apenas um construtor parametrizado, o Java não pode inserir automaticamente super().

❌ Errado:

class Parent {
    Parent(String name) {}
}

class Child extends Parent {
    Child() {
        // compiler tries to insert super() here -> ERROR
    }
}

✅ Correto:

class Child extends Parent {
    Child() {
        super("Taro");
    }
}

Esse é um erro de compilação muito comum para iniciantes, portanto sempre verifique os construtores da classe pai.

5.3 Tentar usar this() e super() no mesmo construtor

Iniciantes costumam pensar:

“Quero chamar outro construtor E o construtor da classe pai.”

Mas o Java não permite isso.

❌ Errado:

class Parent {
    Parent() {}
}

class Child extends Parent {
    Child() {
        this(1);
        super(); // ERROR
    }

    Child(int x) {}
}

Motivo:

  • this() e super() devem ser a primeira linha
  • Apenas um deles pode ser a primeira

Portanto, você deve projetar seus construtores de modo que apenas um seja usado diretamente.

5.4 Tentar usar super dentro de um método estático

super está ligado à instância atual do objeto, portanto não funciona em métodos estáticos.

❌ Errado (conceitualmente):

class Parent {
    void hello() {}
}

class Child extends Parent {
    static void test() {
        super.hello(); // ERROR
    }
}

Ponto chave:

  • Métodos estáticos pertencem à classe, não a uma instância
  • super refere‑se à parte pai de uma instância

Por isso o Java impede isso.

5.5 Entender super como “criar um objeto pai”

Alguns iniciantes assumem:

“Usar super cria um objeto pai separado.”

Isso não é verdade.

super não cria um novo objeto.
Ele simplesmente acessa o lado da classe pai do mesmo objeto.

Pense assim:

  • this = mesmo objeto, visão de filho
  • super = mesmo objeto, visão de pai

5.6 Usar super.campo com muita frequência (esconder campos costuma ser uma má ideia)

Sim, super.campo existe — mas na maioria dos projetos reais, você deve evitar criar campos pai/filho com o mesmo nome.

Exemplo (design confuso):

class Parent {
    int value = 100;
}

class Child extends Parent {
    int value = 200; // hides parent field
}

Mesmo que super.valor funcione, esse design torna o código mais difícil de ler e manter.

Melhor prática:

.

  • Use nomes de campos diferentes
  • Mantenha os campos privados e exponha‑os com métodos (getters)
  • Evite ocultar campos, a menos que seja absolutamente necessário

5.7 “Se eu chamar super.method(), apenas a lógica do pai é executada” (nem sempre)

Isso é um pouco mais avançado, mas útil de saber.

Quando você chama super.method(), você definitivamente chama o método da classe pai.
Entretanto, dentro desse método pai, se ele chamar outro método que a classe filha sobrescreve, a versão da filha pode ser executada.

Exemplo:

class Parent {
    void a() {
        b(); // calls b()
    }

    void b() {
        System.out.println("Parent b()");
    }
}

class Child extends Parent {
    @Override
    void b() {
        System.out.println("Child b()");
    }
}

public class Main {
    public static void main(String[] args) {
        Child c = new Child();
        c.a();
    }
}

Saída:

Child b()

Mesmo que a() esteja na classe pai, ele chama b(), e b() está sobrescrito na classe filha.

Lição para iniciantes:
super.method() chama a versão do método da classe pai, mas chamadas de método dentro dele ainda podem seguir as regras de sobrescrita.

5.8 Checklist rápido (para evitar erros de iniciantes)

Antes de usar super, verifique o seguinte:

  • super(...) é a primeira linha do construtor?
  • A classe pai tem um construtor sem argumentos?
  • Você está tentando usar tanto this() quanto super()?
  • Está usando super dentro de um método estático?
  • Está ocultando campos com o mesmo nome desnecessariamente?

6. Conclusão (Principais aprendizados)

Neste artigo, você aprendeu o que é a palavra‑chave super do Java, por que ela existe e como usá‑la corretamente em código real.

Vamos encerrar tudo com os pontos mais importantes que você deve lembrar.

6.1 O que super significa em Java?

super é uma palavra‑chave que permite acessar explicitamente a parte da classe pai (superclasse) de um objeto.

Ela é usada principalmente em herança (extends) quando você quer referir‑se à versão da classe pai de:

  • construtores
  • métodos
  • campos

Em termos simples:

super significa “usar a versão da classe pai”.

6.2 As 3 maneiras mais importantes de usar super

Você pode memorizar super nesses três padrões:

1) Chamar o construtor da classe pai

  • super()
  • super(args…)

Isso é usado quando você precisa inicializar a classe pai corretamente, especialmente se a classe pai requer argumentos.

2) Chamar o método da classe pai

  • super.method()

É útil quando você sobrescreve um método, mas ainda quer reutilizar o comportamento da classe pai.

3) Acessar o campo da classe pai

  • super.field

É usado quando tanto a classe pai quanto a filha têm um campo com o mesmo nome e você quer referir‑se claramente ao da classe pai.

6.3 this vs super (a forma mais fácil de entender)

Muitos iniciantes confundem essas duas palavras‑chave, mas a diferença é simples:

  • this → o objeto atual (visão da filha)
  • super → a visão da classe pai do mesmo objeto

Eles não representam dois objetos diferentes.

6.4 A maioria dos erros ocorre em torno dos construtores

Se você quiser evitar os erros mais comuns, lembre‑se destas regras:

  • super(...) deve ser a primeira linha dentro de um construtor
  • Se a classe pai não tem um construtor sem argumentos, você deve escrever super(args…)
  • Não é possível usar this() e super() juntos no mesmo construtor
  • super não funciona em métodos estáticos

6.5 Conclusão final: super ajuda a reutilizar e estender a lógica da classe pai com segurança

O verdadeiro poder de super é que ele permite que você:

  • mantenha a lógica compartilhada na classe pai
  • estenda o comportamento na classe filha
  • evite copiar e colar código
  • torne a herança mais limpa e fácil de manter

Se você lembrar de uma única frase deste artigo, lembre‑se desta:

super é a palavra‑chave que você usa quando quer a versão da classe pai.

7. FAQ (Perguntas Frequentes)

Aqui estão as perguntas mais comuns que iniciantes fazem ao aprender a palavra-chave super do Java.
Se você ainda estiver se sentindo inseguro sobre certas partes, esta seção deve esclarecer as coisas rapidamente.

7.1 Quando devo usar super no Java?

Você tipicamente usa super nessas situações:

  • Quando você quer chamar um construtor pai ( super() / super(args...) )
  • Quando você sobrescreve um método mas ainda quer chamar o método pai ( super.method() )
  • Quando o pai e o filho têm o mesmo nome de campo e você quer o campo pai ( super.field )

Para iniciantes, o caso mais comum e útil é:

sobrescrever um método e chamar a lógica pai usando super.method().

7.2 O que acontece se eu não escrever super()?

Se a classe pai tiver um construtor sem argumentos, o Java insere automaticamente:

super();

no topo do construtor filho.

Então, em muitos casos, você não precisa escrevê-lo manualmente.

No entanto, se a classe pai não tiver um construtor sem argumentos, o código falhará a menos que você chame explicitamente o correto com argumentos.

7.3 Qual é a diferença entre super() e this()?

Eles chamam construtores diferentes:

  • super() → chama um construtor na classe pai
  • this() → chama um construtor na mesma classe

Ideia de exemplo:

  • Use this() para reduzir código duplicado de construtor
  • Use super() para inicializar corretamente a parte pai do objeto

7.4 Posso usar tanto this() quanto super() no mesmo construtor?

Não, você não pode.

Razão:

  • Tanto this() quanto super() devem ser a primeira declaração no construtor
  • Apenas uma declaração pode ser a primeira

Então o Java força você a escolher um.

7.5 Posso usar super dentro de um método estático?

Não (em geral).

super está relacionado à instância atual do objeto, mas métodos estáticos pertencem à classe em si e não têm uma referência de instância.

É por isso que usar super em métodos estáticos resulta em um erro de compilação.

7.6 O super cria um novo objeto pai?

Não.

super não cria nenhum novo objeto.

Ele simplesmente acessa a visão da classe pai do mesmo objeto.

Uma forma útil de pensar sobre isso:

  • this = mesmo objeto visto como filho
  • super = mesmo objeto visto como pai

7.7 Se eu chamar super.method(), ele sempre executa apenas a lógica pai?

super.method() sempre chama a versão pai desse método.

No entanto, se o método pai chamar internamente outro método que o filho sobrescreve, então a versão do filho pode executar devido às regras de sobrescrita do Java.

Ponto de partida para iniciantes:

super.method() chama a versão pai, mas chamadas de método dentro dele ainda podem ser afetadas pela sobrescrita.

7.8 Devo usar super.field frequentemente?

Geralmente, não.

Se você frequentemente precisar de super.field, isso pode significar que seu design está confuso porque o pai e o filho compartilham o mesmo nome de campo.

Em projetos reais, é melhor evitar o ocultamento de campos a menos que você tenha uma forte razão (como código legado ou restrições externas).

7.9 O super pode ser usado com interfaces?

Na herança normal (extends), super refere-se à classe pai.

No entanto, o Java também permite uma sintaxe especial para chamar um método padrão de interface:

InterfaceName.super.method();

Isso é mais avançado, então se você é iniciante, foque primeiro em:

  • herança de classe
  • super() / super.method() / super.field

7.10 Qual é a forma mais rápida de dominar super?

Um caminho de aprendizado simples:

  1. Escreva uma classe pai/filho básica e confirme a ordem do construtor
  2. Sobrescreva um método e chame super.method()
  3. Compare this vs super com campos e métodos
  4. Pratique corrigindo erros relacionados a construtores

A melhor prática é escrever pequenos exemplos e executá-los.