logo

Polimorfismo em Java

Polimorfismo em Java é um conceito pelo qual podemos realizar um ação única de maneiras diferentes . O polimorfismo é derivado de 2 palavras gregas: poli e morfos. A palavra 'poli' significa muitos e 'morfos' significa formas. Portanto, polimorfismo significa muitas formas.

Existem dois tipos de polimorfismo em Java: polimorfismo em tempo de compilação e polimorfismo em tempo de execução. Podemos realizar polimorfismo em java por sobrecarga e substituição de método.

Se você sobrecarregar um método estático em Java, será um exemplo de polimorfismo em tempo de compilação. Aqui, focaremos no polimorfismo de tempo de execução em java.


Polimorfismo de tempo de execução em Java

Polimorfismo de tempo de execução ou Envio de Método Dinâmico é um processo no qual uma chamada para um método substituído é resolvida em tempo de execução, e não em tempo de compilação.

Neste processo, um método substituído é chamado através da variável de referência de uma superclasse. A determinação do método a ser chamado é baseada no objeto ao qual a variável de referência se refere.

Vamos primeiro entender o upcasting antes do polimorfismo em tempo de execução.

Upcasting

Se a variável de referência da classe Parent se referir ao objeto da classe Child, isso é conhecido como upcasting. Por exemplo:

Upcasting em Java
 class A{} class B extends A{} 
 A a=new B();//upcasting 

Para upcasting, podemos usar a variável de referência do tipo de classe ou um tipo de interface. Por exemplo:

 interface I{} class A{} class B extends A implements I{} 

Aqui, a relação da classe B seria:

 B IS-A A B IS-A I B IS-A Object 

Como Object é a classe raiz de todas as classes em Java, podemos escrever B IS-A Object.


Exemplo de polimorfismo de tempo de execução Java

Neste exemplo, estamos criando duas classes Bike e Splendor. A classe Splendor estende a classe Bike e substitui seu método run(). Estamos chamando o método run pela variável de referência da classe Parent. Como se refere ao objeto da subclasse e o método da subclasse substitui o método da classe Parent, o método da subclasse é invocado em tempo de execução.

python classificando tuplas

Como a invocação do método é determinada pela JVM e não pelo compilador, isso é conhecido como polimorfismo de tempo de execução.

 class Bike{ void run(){System.out.println('running');} } class Splendor extends Bike{ void run(){System.out.println('running safely with 60km');} public static void main(String args[]){ Bike b = new Splendor();//upcasting b.run(); } } 
Teste agora

Saída:

o que é hibernar
 running safely with 60km. 

Exemplo de polimorfismo de tempo de execução Java: banco

Considere um cenário onde Bank é uma classe que fornece um método para obter a taxa de juros. No entanto, a taxa de juros pode variar de acordo com os bancos. Por exemplo, os bancos SBI, ICICI e AXIS oferecem taxas de juros de 8,4%, 7,3% e 9,7%.

Exemplo de banco Java Runtime Polymorphism

Nota: Este exemplo também é fornecido na substituição de método, mas não houve upcasting.

 class Bank{ float getRateOfInterest(){return 0;} } class SBI extends Bank{ float getRateOfInterest(){return 8.4f;} } class ICICI extends Bank{ float getRateOfInterest(){return 7.3f;} } class AXIS extends Bank{ float getRateOfInterest(){return 9.7f;} } class TestPolymorphism{ public static void main(String args[]){ Bank b; b=new SBI(); System.out.println('SBI Rate of Interest: '+b.getRateOfInterest()); b=new ICICI(); System.out.println('ICICI Rate of Interest: '+b.getRateOfInterest()); b=new AXIS(); System.out.println('AXIS Rate of Interest: '+b.getRateOfInterest()); } } 
Teste agora

Saída:

 SBI Rate of Interest: 8.4 ICICI Rate of Interest: 7.3 AXIS Rate of Interest: 9.7 

Exemplo de polimorfismo de tempo de execução Java: forma

 class Shape{ void draw(){System.out.println('drawing...');} } class Rectangle extends Shape{ void draw(){System.out.println('drawing rectangle...');} } class Circle extends Shape{ void draw(){System.out.println('drawing circle...');} } class Triangle extends Shape{ void draw(){System.out.println('drawing triangle...');} } class TestPolymorphism2{ public static void main(String args[]){ Shape s; s=new Rectangle(); s.draw(); s=new Circle(); s.draw(); s=new Triangle(); s.draw(); } } 
Teste agora

Saída:

 drawing rectangle... drawing circle... drawing triangle... 

Exemplo de polimorfismo de tempo de execução Java: Animal

 class Animal{ void eat(){System.out.println('eating...');} } class Dog extends Animal{ void eat(){System.out.println('eating bread...');} } class Cat extends Animal{ void eat(){System.out.println('eating rat...');} } class Lion extends Animal{ void eat(){System.out.println('eating meat...');} } class TestPolymorphism3{ public static void main(String[] args){ Animal a; a=new Dog(); a.eat(); a=new Cat(); a.eat(); a=new Lion(); a.eat(); }} 
Teste agora

Saída:

 eating bread... eating rat... eating meat... 

Polimorfismo Java Runtime com membro de dados

Um método é substituído, não os membros dos dados, portanto, o polimorfismo de tempo de execução não pode ser alcançado pelos membros dos dados.

No exemplo abaixo, ambas as classes possuem um limite de velocidade de membro de dados. Estamos acessando o membro de dados pela variável de referência da classe Parent que se refere ao objeto da subclasse. Como estamos acessando o membro de dados que não é substituído, ele sempre acessará o membro de dados da classe Parent.

Regra: O polimorfismo de tempo de execução não pode ser alcançado por membros de dados.

 class Bike{ int speedlimit=90; } class Honda3 extends Bike{ int speedlimit=150; public static void main(String args[]){ Bike obj=new Honda3(); System.out.println(obj.speedlimit);//90 } } 
Teste agora

Saída:

 90 

Polimorfismo Java Runtime com herança multinível

Vamos ver o exemplo simples de Polimorfismo de Tempo de Execução com herança multinível.

 class Animal{ void eat(){System.out.println('eating');} } class Dog extends Animal{ void eat(){System.out.println('eating fruits');} } class BabyDog extends Dog{ void eat(){System.out.println('drinking milk');} public static void main(String args[]){ Animal a1,a2,a3; a1=new Animal(); a2=new Dog(); a3=new BabyDog(); a1.eat(); a2.eat(); a3.eat(); } } 
Teste agora

Saída:

 eating eating fruits drinking Milk 

Experimente a saída

 class Animal{ void eat(){System.out.println('animal is eating...');} } class Dog extends Animal{ void eat(){System.out.println('dog is eating...');} } class BabyDog1 extends Dog{ public static void main(String args[]){ Animal a=new BabyDog1(); a.eat(); }} 
Teste agora

Saída:

 Dog is eating 

Como BabyDog não está substituindo o método eat(), o método eat() da classe Dog é invocado.