A palavra polimorfismo é usado em vários contextos e descreve situações em que algo ocorre em várias formas diferentes. Em Ciência da computação, descreve o conceito de que objetos de diferentes tipos podem ser acessados através da mesma interface. Cada tipo pode fornecer a sua própria implementação independente desta interface. É um dos conceitos centrais da programação orientada a objetos (OOP).,
Se você está se perguntando se um objeto é polimórfico, você pode realizar um teste simples. Se o objeto passa com sucesso múltiplos testes is-a ou instanceof, é polimórfico. Como eu descrevi no meu post sobre herança, todas as classes Java estendem o objeto de classe. Devido a isso, todos os objetos em Java são polimórficos porque eles passam pelo menos dois instanceof checks.,
Diferentes tipos de polimorfismo
Java suporta 2 tipos de polimorfismo:
- estáticas ou em tempo de compilação
- dinâmica
polimorfismo Estático
Java, como muitas outras linguagens de programação orientada, permite implementar vários métodos, dentro da mesma classe que use o mesmo nome, mas um conjunto diferente de parâmetros. Isso é chamado de sobrecarga de método e representa uma forma estática de polimorfismo.,
os conjuntos de parâmetros têm de diferir em pelo menos um dos três critérios seguintes:
- eles precisam ter um número diferente de parâmetros, por exemplo, um método Aceita 2 e outro 3 parâmetros.
- os tipos dos parâmetros precisam ser diferentes, por exemplo, um método aceita uma cadeia e outro um longo.
- eles precisam esperar os parâmetros em uma ordem diferente, por exemplo, um método aceita uma cadeia e um longo e outro aceita uma cadeia longa e uma cadeia. Este tipo de sobrecarga não é recomendado porque torna a API difícil de entender.,
na maioria dos casos, cada um destes métodos sobrecarregados fornece uma funcionalidade diferente mas muito semelhante.
devido aos diferentes conjuntos de Parâmetros, cada método tem uma assinatura diferente. Isso permite ao compilador identificar qual método tem que ser chamado e vinculá-lo à chamada de método. Esta abordagem é chamada de ligação estática ou polimorfismo estático.
vamos dar uma olhada em um exemplo.
um exemplo simples para polimorfismo estático
eu uso o mesmo projeto CoffeeMachine que eu usei nos posts anteriores desta série. Você pode cloná-lo em https://github.com/thjanssen/Stackify-OopInheritance.,
A classe BasicCoffeeMachine implementa dois métodos com o nome de brewCoffee. O primeiro aceita um parâmetro de tipo CoffeeSelection. O outro método aceita dois parâmetros, um CoffeeSelection, e um int.
Agora, quando você chama um destes métodos, o conjunto de parâmetros fornecidos identifica o método que tem que ser chamado.
no seguinte trecho de código, eu chamo o método apenas com um objeto de CoffeeSelection. No tempo de compilação, o compilador Java liga este método ao método brewCoffee (CoffeeSelection selection).,
BasicCoffeeMachine coffeeMachine = createCoffeeMachine();coffeeMachine.brewCoffee(CoffeeSelection.FILTER_COFFEE);
If I change this code and call the brewCoffee method with a CoffeeSelection object and an int, the compiler binds the method call to the other brewCoffee(CoffeeSelection selection, int number) method.
polimorfismo dinâmico
Esta forma de polimorfismo não permite que o compilador determine o método executado. O JVM precisa de fazer isso a tempo de execução.
dentro de uma hierarquia de herança, uma subclasse pode sobrepor um método de sua superclasse. Isso permite que o desenvolvedor da subclasse personalize ou substitua completamente o comportamento desse método.,
também cria uma forma de polimorfismo. Ambos os métodos, implementados pela super e subclasse, compartilham o mesmo nome e parâmetros, mas fornecem funcionalidades diferentes.
vamos dar uma olhada em outro exemplo do projeto CoffeeMachine.
método que prevalece numa hierarquia de hereditariedade
a classe BasicCoffeeMachine é a superclasse da classe PremiumCoffeeMachine.ambas as classes fornecem uma aplicação do método brewCoffee(CoffeeSelection selection).,
Se você ler o post sobre a herança conceito OOP, você já conhece as duas implementações do método brewCoffee. A máquina de café de Base só suporta a selecção dos cofres.FILTER_ coffee. O método brewCoffee da classe PremiumCoffeeMachine adiciona suporte para a seleção de café.CAFE. Se ele é chamado com qualquer outra CoffeeSelection, ele usa a palavra-chave super para delegar a chamada para a superclasse.,
ligação tardia
quando você quer usar essa hierarquia de herança em seu projeto, você precisa ser capaz de responder à seguinte pergunta: Que método a JVM chamará?
Que só pode ser respondida em tempo de execução porque depende do objeto no qual o método é chamado. O tipo de referência, que você pode ver em seu código, é irrelevante. Você precisa distinguir três cenários gerais:
- Seu objeto é do tipo da superclasse e é referenciado como a superclasse., Assim, no exemplo deste post, um objeto BasicCoffeeMachine é referenciado como um BasicCoffeeMachine.
- Seu objeto é do tipo da subclasse e é referenciado como a subclasse. In the example of this post, a PremiumCoffeeMachine object gets referenced as a PremiumCoffeeMachine.
- Seu objeto é do tipo da subclasse e é referenciado como a superclasse. No exemplo de CoffeeMachine, um objeto Premium coffeemachine é referenciado como um BasicCoffeeMachine.
superclasse referenciada como a superclasse
o primeiro cenário é bastante simples., Quando instanciar um objecto BasicCoffeeMachine e armazená-lo numa variável do tipo BasicCoffeeMachine, a JVM chamará o método brewCoffee na classe BasicCoffeeMachine. Então, só se pode fazer uma selecção de café.FILTER_ coffee.
subclasse referenciada como a subclasse
o segundo cenário é similar. Mas desta vez, instanciei uma Estreumcoffeemachine e referenciei-a como uma PremiumCoffeeMachine. Neste caso, a JVM chama o método brewCoffee da classe PremiumCoffeeMachine, que adiciona suporte para a seleção de café.CAFE.,
subclasse referenciada como a superclasse
Este é o cenário mais interessante e a principal razão pela qual eu explico polimorfismo dinâmico em tais detalhes.
When you instantiate a PremiumCoffeeMachine object and assign it to the BasicCoffeeMachine coffeeMachine variable, it still is a PremiumCoffeeMachine object. Parece uma bebida de base.
O compilador não vê isso no código, e você só pode usar os métodos fornecidos pela classe BasicCoffeeMachine., Mas se você chamar o método brewCoffee na variável coffeeMachine, a JVM sabe que é um objeto do tipo PremiumCoffeeMachine e executa o método overridden. Isto é chamado de ligação tardia.
resumo
polimorfismo é um dos conceitos centrais nas línguas OOP. Descreve o conceito de que diferentes classes podem ser usadas com a mesma interface. Cada uma dessas classes pode fornecer sua própria implementação da interface.
Java suporta dois tipos de polimorfismo. Você pode sobrecarregar um método com diferentes conjuntos de parâmetros., Isto é chamado de polimorfismo estático porque o compilador estaticamente liga o método chamado a um método específico.
dentro de uma hierarquia de herança, uma subclasse pode sobrepor um método de sua superclasse. Se você instanciar a subclasse, a JVM sempre chamará o método sobreposto, mesmo se você lançar a subclasse para a sua superclasse. Isso é chamado polimorfismo dinâmico.