Qual é a diferença entre polymorphism dynamic e estático em Java?

Alguém pode fornecer um exemplo simples que explica a diferença entre o polymorphism dynamic e estático em Java?

Polimorfismo

1. Ligação estática / Ligação em tempo de compilation / Ligação antecipada / Sobrecarga de método (na mesma class)

2. Ligação dinâmica / Ligação em tempo de execução / Ligação atrasada / Substituição de método (em classs diferentes)

Exemplo de sobrecarga:

class Calculation { void sum(int a,int b){System.out.println(a+b);} void sum(int a,int b,int c){System.out.println(a+b+c);} public static void main(String args[]) { Calculation obj=new Calculation(); obj.sum(10,10,10); // 30 obj.sum(20,20); //40 } } 

exemplo de substituição:

 class Animal { public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal { public void move() { System.out.println("Dogs can walk and run"); } } public class TestDog { public static void main(String args[]) { Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move();//output: Animals can move b.move();//output:Dogs can walk and run } } 
  • Sobrecarga de método seria um exemplo de polymorphism estático

  • enquanto ignorar seria um exemplo de polymorphism dynamic.

    Porque, em caso de sobrecarga, em tempo de compilation o compilador sabe qual método vincular à chamada. No entanto, é determinado em tempo de execução para o polymorphism dynamic

O polymorphism dynamic (tempo de execução) é o polymorphism existente em tempo de execução. Aqui, o compilador Java não entende qual método é chamado no momento da compilation. Apenas a JVM decide qual método é chamado em tempo de execução. A sobrecarga de methods e a substituição de methods usando methods de instância são exemplos de polymorphism dynamic.

Por exemplo,

  • Considere um aplicativo que serializa e desserializa diferentes tipos de documentos.

  • Podemos ter ‘Document’ como a class base e diferentes classs de tipos de documentos derivados dela. Por exemplo, XMLDocument, WordDocument, etc.

  • A class do documento definirá os methods ‘Serialize ()’ e ‘De-serialize ()’ como virtuais e cada class derivada implementará esses methods à sua maneira, com base no conteúdo real dos documentos.

  • Quando diferentes tipos de documentos precisam ser serializados / de-serializados, os objects do documento serão referenciados pela referência de class ‘Document’ (ou ponteiro) e quando o método ‘Serialize ()’ ou ‘De-serialize ()’ for chamado. nele, são chamadas versões apropriadas dos methods virtuais.

O polymorphism estático (tempo de compilation) é o polymorphism exibido em tempo de compilation. Aqui, o compilador Java sabe qual método é chamado. Sobrecarga de método e substituição de methods usando methods estáticos; substituição de método usando methods privados ou finais são exemplos de polymorphism estático

Por exemplo,

  • Um object empregado pode ter dois methods print (), um sem argumentos e outro com uma cadeia de prefixo a ser exibida junto com os dados do empregado.

  • Dadas essas interfaces, quando o método print () é chamado sem nenhum argumento, o compilador, observando os argumentos da function, sabe qual function deve ser chamada e gera o código do object de acordo.

Para mais detalhes, leia “O que é polymorphism” (Google it).

Polimorfismo: Polimorfismo é a capacidade de um object assumir muitas formas. O uso mais comum de polymorphism na OOP ocorre quando uma referência de class pai é usada para se referir a um object de class filho.

Polimorfismo de Ligação Dinâmica / Tempo de Execução:

Tempo de execução Polimorfismo também conhecido como substituição de método. Neste mecanismo pelo qual uma chamada para uma function substituída é resolvida em um tempo de execução.

 public class DynamicBindingTest { public static void main(String args[]) { Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car vehicle.start(); //Car's start called because start() is overridden method } } class Vehicle { public void start() { System.out.println("Inside start method of Vehicle"); } } class Car extends Vehicle { @Override public void start() { System.out.println("Inside start method of Car"); } } 

Saída:

Dentro de método de começo de Carro

Polimorfismo de Ligação Estática / Tempo de Compilação:

Qual método deve ser chamado é decidido somente em tempo de compilation.

 public class StaticBindingTest { public static void main(String args[]) { Collection c = new HashSet(); StaticBindingTest et = new StaticBindingTest(); et.sort(c); } //overloaded method takes Collection argument public Collection sort(Collection c){ System.out.println("Inside Collection sort method"); return c; } //another overloaded method which takes HashSet argument which is sub class public Collection sort(HashSet hs){ System.out.println("Inside HashSet sort method"); return hs; } } 

Saída: Inside Collection sort metho

A sobrecarga de método é um exemplo de static polymorphism compile time / static polymorphism de compile time porque a vinculação de método entre a chamada do método e a definição do método ocorre no momento da compilation e depende da referência da class (referência criada no tempo de compilation e vai para a pilha).

A substituição de método é um exemplo de run time de run time / dynamic polymorphism porque a vinculação de método entre a chamada do método e a definição do método ocorre no tempo de execução e depende do object da class (object criado no tempo de execução e vai para o heap).

Em termos simples :

Polimorfismo estático : O mesmo nome do método está sobrecarregado com diferentes tipos ou números de parâmetros na mesma class (assinatura diferente). Chamada de método direcionada é resolvida em tempo de compilation.

Polimorfismo dynamic : o mesmo método é substituído pela mesma assinatura em classs diferentes . O tipo de object no qual o método está sendo chamado não é conhecido em tempo de compilation, mas será decidido no tempo de execução.

Geralmente a sobrecarga não será considerada como polymorphism.

Na página de tutorial do java:

As subclasss de uma class podem definir seus próprios comportamentos exclusivos e ainda compartilhar algumas das mesmas funcionalidades da class pai

Ligação refere-se ao link entre a chamada do método e a definição do método.

Esta imagem mostra claramente o que é obrigatório.

obrigatório

Nesta imagem, a chamada “a1.methodOne ()” é vinculativa para a definição methodOne () correspondente e a chamada “a1.methodTwo ()” está vinculada à definição methodTwo () correspondente.

Para cada chamada de método, deve haver uma definição adequada do método. Esta é uma regra em java. Se o compilador não vir a definição de método apropriada para cada chamada de método, isso causará erro.

Agora, venha para binding estática e binding dinâmica em java.

Ligação estática em Java:

Ligação estática é uma binding que acontece durante a compilation. Ele também é chamado de binding antecipada porque a binding ocorre antes de um programa ser executado

.

A binding estática pode ser demonstrada como na figura abaixo.

insira a descrição da imagem aqui

Nesta figura, ‘a1’ é uma variável de referência do tipo A que aponta para o object da class A. ‘a2’ também é uma variável de referência do tipo class A, mas apontando para o object da Classe B.

Durante a compilation, durante a vinculação, o compilador não verifica o tipo de object para o qual uma determinada variável de referência está apontando. Ele apenas verifica o tipo de variável de referência através do qual um método é chamado e verifica se existe uma definição de método para ele nesse tipo.

Por exemplo, para a chamada do método “a1.method ()” na figura acima, o compilador verifica se existe uma definição de método para o método () na Classe A. Porque ‘a1’ é do tipo Classe A. Da mesma forma, para a chamada de método “a2.method ()”, verifica se existe uma definição de método para method () na Classe A. Porque ‘a2’ também é do tipo Classe A. Não verifica a qual object, ‘a1’ e ‘a2’ estão apontando. Esse tipo de binding é chamado de binding estática.

Ligação Dinâmica Em Java:

Ligação dinâmica é uma binding que acontece durante o tempo de execução. Ele também é chamado de binding tardia porque a binding ocorre quando o programa está sendo executado.

Durante o tempo de execução, os objects reais são usados ​​para encadernação. Por exemplo, para a chamada “a1.method ()” na figura acima, method () do object real para o qual ‘a1’ está apontando será chamado. Para a chamada “a2.method ()”, method () do object real para o qual ‘a2’ está apontando será chamado. Esse tipo de binding é chamado de binding dinâmica.

A binding dinâmica do exemplo acima pode ser demonstrada como abaixo.

insira a descrição da imagem aqui

Referência estática-binding-e-dynamic-binding-in-java

Polimorfismo Estático: é onde a decisão de resolver qual método realizar é determinada durante o tempo de compilation. Sobrecarga de método poderia ser um exemplo disso.

Polimorfismo Dinâmico: é onde a decisão de escolher o método a ser executado é definida durante o tempo de execução. Método Overriding poderia ser um exemplo disso.

Sobrecarga de método é conhecido como polymorphism estático e também conhecido como polymorphism de tempo de compilation ou vinculação estática porque chamadas de método sobrecarregado são resolvidas em tempo de compilation pelo compilador com base na lista de argumentos ea referência na qual estamos chamando o método.

E o método Overriding é conhecido como Polimorfismo Dinâmico ou Polimorfismo Simples ou Despacho de Método de Tempo de Execução ou Ligação Dinâmica porque a chamada do método substituído é resolvida em tempo de execução.

Para entender por que isso é assim, vamos dar um exemplo da class Mammal e Human

 class Mammal { public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); } } class Human extends Mammal { @Override public void speak() { System.out.println("Hello"); } public void speak(String language) { if (language.equals("Hindi")) System.out.println("Namaste"); else System.out.println("Hello"); } } 

Eu incluí a saída, bem como bytecode de abaixo linhas de código

 Mammal anyMammal = new Mammal(); anyMammal.speak(); // Output - ohlllalalalalalaoaoaoa // 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V Mammal humanMammal = new Human(); humanMammal.speak(); // Output - Hello // 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V Human human = new Human(); human.speak(); // Output - Hello // 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V human.speak("Hindi"); // Output - Namaste // 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V 

E observando o código acima, podemos ver que os bytecodes de humanMammal.speak (), human.speak () e human.speak (“Hindi”) são totalmente diferentes porque o compilador é capaz de diferenciá-los com base na lista de argumentos. e referência de class. E é por isso que o Sobrecarga de Método é conhecido como Polimorfismo Estático .

Mas o bytecode para anyMammal.speak () e humanMammal.speak () é o mesmo porque, de acordo com o compilador, ambos os methods são chamados na referência Mammal, mas a saída para ambas as chamadas de método é diferente porque, em tempo de execução, a JVM sabe qual object uma referência está mantendo e chamadas da JVM o método no object e é por isso que o método Overriding é conhecido como Polimorfismo Dinâmico.

Portanto, a partir do código acima e do bytecode, é claro que durante a fase de compilation, o método de chamada é considerado do tipo de referência. Mas no momento da execução, o método será chamado a partir do object que a referência está mantendo.

Se você quiser saber mais sobre isso, leia mais sobre Como o método de processamento da JVM sobrecarrega e sobrescreve internamente .

Polimorfismo no tempo de compilation (Ligação Estática / Ligação Precoce): No polymorphism estático, se chamarmos um método em nosso código, então qual definição desse método deve ser chamada, na verdade, é resolvida apenas em tempo de compilation.

(ou)

Em tempo de compilation, Java sabe qual método invocar, verificando as assinaturas do método. Então, isso é chamado de polymorphism em tempo de compilation ou binding estática.

Polimorfismo Dinâmico (Polimorfismo de Ligação Atrasada / Tempo de Execução): No tempo de execução, o Java aguarda até o tempo de execução para determinar qual object está realmente sendo apontado pela referência. A resolução do método foi tomada em tempo de execução, devido ao que chamamos de polymorphism de tempo de execução.

A sobrecarga de método é um polymorphism em tempo de compilation, vamos dar um exemplo para entender o conceito.

 class Person //person.java file { public static void main ( String[] args ) { Eat e = new Eat(); e.eat(noodle); //line 6 } void eat (Noodles n) //Noodles is a object line 8 { } void eat ( Pizza p) //Pizza is a object { } } 

Neste exemplo, Person tem um método de comer que representa que ele pode comer Pizza ou Macarrão. Que o método eat esteja sobrecarregado quando compilamos este Person.java o compilador resolve a chamada do método “e.eat (noodles) [que está na linha 6] com a definição do método especificada na linha 8 que é o método que pega noodles como parâmetro e todo o processo é feito pelo Compiler assim é o polymorphism tempo de compilation.O processo de substituição da chamada do método com a definição do método é chamado de binding, neste caso, é feito pelo compilador para que ele seja chamado de binding antecipada.

Polimorfismo refere-se à capacidade de um object se comportar de maneira diferente para o mesmo gatilho.

Polimorfismo Estático (Polimorfismo no Tempo de Compilação)

  • O polymorphism estático decide qual método executar durante o tempo de compilation.
  • Sobrecarga de método é um exemplo de polymorphism estático, e é requerido que ocorra polymorphism estático.
  • Polimorfismo Estático obtido através de binding estática.
  • O polymorphism estático ocorre na mesma class.
  • Atribuição de object não é necessária para polymorphism estático.
  • Herança não envolvida para polymorphism estático.

Polimorfismo Dinâmico (Polimorfismo em Tempo de Execução)

  • Polimorfismo dynamic decide qual método executar em tempo de execução.
  • Método Overriding é um exemplo de polymorphism dynamic, e é necessário que ocorra polymorphism dynamic.
  • Polimorfismo Dinâmico alcançado através de binding dinâmica.
  • O polymorphism dynamic acontece entre diferentes classs.
  • É necessário onde um object de subclass é atribuído ao object de superclass para o polymorphism dynamic.
  • Herança envolvida no polymorphism dynamic.