logo

Substituindo em Java

Quando uma subclasse fornece uma implementação específica para um método que já está definido em sua classe pai, ela é chamada de substituição de método. O método substituído na subclasse deve ter os mesmos parâmetros de nome e tipo de retorno que o método na classe pai.

Regras para substituição de método

  • Os parâmetros de nome e o tipo de retorno devem corresponder ao método pai.
  • Java escolhe qual método executar em tempo de execução com base no tipo de objeto real e não apenas no tipo de variável de referência.
  • Os métodos estáticos não podem ser substituídos.
  • O @Override anotação detecta erros como erros de digitação em nomes de métodos.
Java
class Animal {    void move(){  System.out.println(  'Animal is moving.');     }  void eat(){    System.out.println(  'Animal is eating.');     } } class Dog extends Animal{    @Override void move(){     // move method from Base class is overriden in this  // method  System.out.println('Dog is running.');  }  void bark(){    System.out.println('Dog is barking.');     } } public class Geeks {  public static void main(String[] args)  {  Dog d = new Dog();  d.move();   d.eat();   d.bark();  } } 

Saída
Dog is running. Animal is eating. Dog is barking. 

Explicação: A classe Animal define funcionalidades básicas como mover() e comer() . A classe Dog herda de Animal e substituições o método move() para fornecer um comportamento específico O cachorro está correndo. Ambas as classes podem acessar seus próprios métodos. Ao criar um objeto Dog, chamar move() executa o método substituído.



Substituição de método em Java' title=

Casos especiais em substituição

1. Chamando o método pai usando super

O super palavra-chave pode invocar o método da classe pai a partir do método de substituição.

Java
class Parent{    void show(){    System.out.println('Parent's show()');  } } class Child extends Parent{    @Override  void show(){    super.show();  System.out.println('Child's show()');  } } public class Main{    public static void main(String[] args){    Parent obj = new Child();  obj.show();  } } 

Saída
Parent's show() Child's show() 

2.  Os métodos finais não podem ser substituídos

Se não quisermos que um método seja substituído, declaramo-lo como  final . Por favor veja  Usando Final com Herança

autômatos finitos determinísticos
Java
class Parent{    // Can't be overridden  final void show(){    } } class Child extends Parent{    // This would produce error  void show() {} } 


Saída :



Substituição de método' loading='lazy' title=

3. Métodos estáticos

  • Os métodos estáticos não podem ser substituídos; definir um método estático em uma subclasse com a mesma assinatura da superclasse oculta o método da superclasse.
  • Os métodos de instância podem ser substituídos, mas uma subclasse não pode substituir um método estático da superclasse.
  • Um método estático em uma subclasse com a mesma assinatura de um método estático da superclasse oculta o método original.
Java
class Parent{  static void staticMethod(){    System.out.println('Parent static method');  }  void instanceMethod(){    System.out.println('Parent instance method');  } } class Child extends Parent{    static void staticMethod(){    // Hides Parent's static method  System.out.println('Child static method');  }  @Override  void instanceMethod(){     // Overrides Parent's instance method  System.out.println('Child instance method');  } } public class GFG{    public static void main(String[] args){    Parent p = new Child();    // Calls Parent's static method (hiding)  p.staticMethod();    // Calls Child's overridden instance method  p.instanceMethod();   } } 

Saída
Parent static method Child instance method 

4. Métodos Privados

  • Os métodos privados não podem ser substituídos porque não são visíveis para as subclasses.
  • Um método de subclasse com o mesmo nome é tratado como um novo método independente não relacionado à classe pai.
Java
class Parent{    private void display(){    System.out.println('Parent private method');  } } class Child extends Parent{    void display(){    // This is a new method not overriding  System.out.println('Child method');  } } public class GFG{    public static void main(String[] args){    Child c = new Child();    // Calls Child's method  c.display();   } } 

Saída
Child method 

5. Tipos de retorno covariante

  • Na substituição de método, o tipo de retorno do método substituído pode ser uma subclasse do tipo de retorno do método substituído.
  • Este recurso é conhecido como tipo de retorno covariante e permite tipos de retorno mais específicos na subclasse.
Java
class Parent{    Parent getObject(){    System.out.println('Parent object');  return new Parent();  } } class Child extends Parent{    @Override    // Covariant return type  Child getObject() {   System.out.println('Child object');  return new Child();  } } public class GFG{    public static void main(String[] args){    Parent obj = new Child();    // Calls Child's method  obj.getObject();     } } 

Saída
Child object 

Tratamento de exceções na substituição

  • O método de substituição não pode lançar exceções verificadas novas ou mais amplas do que o método na superclasse.
  • Ele pode gerar menos exceções verificadas ou mais restritas.
  • Ele pode lançar qualquer exceção não verificada (como RuntimeException), independentemente do método da superclasse.
Java
import java.io.IOException; class Parent {  void display() throws IOException {  System.out.println('Parent method');  } } class Child extends Parent {  @Override  void display() throws IOException {  System.out.println('Child method');  } } public class GFG{    public static void main(String[] args){    // Parent reference Child object  Parent obj = new Child();   try{    // Calls Child's overridden method  obj.display();   } catch (IOException e){    System.out.println('Exception caught: ' + e.getMessage());  }  } } 

Saída
Child method 

Por que usamos substituição de método?

  • Para alterar ou aprimorar o comportamento de um método existente em uma subclasse.
  • Para obter polimorfismo em tempo de execução — as chamadas de método dependem do tipo de objeto real.
  • Reutilizar nomes de métodos reduzindo logicamente a redundância.

Exemplo da vida real: sistema de gestão de funcionários

Vamos entender a substituição com uma analogia do mundo real.

Imagine o Sistema de Gestão de Funcionários de uma organização. Todos os funcionários compartilham alguns comportamentos como raiseSalary() e promote() mas a lógica difere para diferentes funções, como Gerente ou Engenheiro. Podemos criar um único array Employee onde funcionários individuais são de diferentes tipos (técnico de vendas, etc.) e chamar suas funções. Isso simplifica muito o código geral.

Java
abstract class Employee {  abstract void raiseSalary();  abstract void promote(); } class Manager extends Employee{  @Override void raiseSalary(){    System.out.println(  'Manager salary raised with incentives.');  }  @Override void promote(){    System.out.println(  'Manager promoted to Senior Manager.');  } } class Engineer extends Employee{    @Override void raiseSalary(){    System.out.println(  'Engineer salary raised with bonus.');  }  @Override void promote(){    System.out.println(  'Engineer promoted to Senior Engineer.');  } } public class Company{    public static void main(String[] args){    Employee[] employees  = { new Manager() new Engineer() };  System.out.println('--- Raising Salaries ---');  for (Employee e : employees){    e.raiseSalary();   }  System.out.println('n--- Promotions ---');  for (Employee e : employees) {  e.promote();  }  } } 

Saída
--- Raising Salaries --- Manager salary raised with incentives. Engineer salary raised with bonus. --- Promotions --- Manager promoted to Senior Manager. Engineer promoted to Senior Engineer. 

Explicação: Embora os objetos Manager e Engineer sejam referidos usando o tipo Employee, Java chama os métodos substituídos dos objetos reais em tempo de execução, demonstrando o envio de método dinâmico (polimorfismo de tempo de execução).



Kat Timpf é advogada

Artigo relacionado: Sobrecarga e substituição de método