No vídeo a seguir mostramos passo a passo como funciona o polimorfismo:
Quando trabalhamos com herança e dizemos que uma subclasse PessoaFisica e PessoaJuridica são filhas da super classe Pessoa, podemos então dizer que um PessoaFisica É UMA Pessoa e PessoaJuridica É UMA Pessoa, justamente por ser uma extensão ou tipo mais especificado deste. Essa é a semântica da herança.
Dizer que uma Pessoa É UMA PessoaFisica está errado, porque ela pode também ser uma PessoaJuridica.
Quando trabalhamos com uma variável do tipo Pessoa que é uma super classe, podemos fazer está variável receber um objeto do tipo PessoaFisica ou PessoaJuridica, por exemplo:
Com isso, podemos dizer que polimorfismo é a capacidade de um objeto ser referenciado de diversas formas diferentes e com isso realizar as mesmas tarefas (ou chamadas de métodos) de diferentes formas.
Um exemplo do uso do polimorfismo utilizando a classe Pessoa, seria todas as subclasses sobrescreverem o método public String getNome().
A subclasse PessoFisica sobrescreve o método public String getNome() e retorna a seguinte frase: “Pessoa Fisica: nomePessoa – CPF: cpfPessoa”.
A subclasse PessoaJuridica sobrescreve o método public String getNome() e retorna a seguinte frase: “Pessoa Juridica: nomePessoa – CNPJ: cnpjPessoa”.
Desta maneira, independentemente do nosso objeto PessoaFisica e PessoaJuridica ter sido atribuído a uma referencia para Pessoa, quando chamamos o método public String getNome() de ambas variáveis, temos a seguinte saída:
Exemplo:
Saída:
Mesmo as variáveis sendo do tipo Pessoa, o método public String getNome() foi chamado da classe PessoaFisica e PessoaJuridica, porque durante a execução do programa, a JVM percebe que a variável fisica está guardando um objeto do tipo PessoaFisica, e a variável juridica está guardando um objeto do tipo PessoaJuridica.
Note que neste exemplo apenas atribuímos o valor do nome da Pessoa, não informamos qual o CPF ou CNPJ da pessoa, se tentarmos utilizar a variável do tipo Pessoa para atribuir o CPF através do método public void setCpf(long cpf) teremos um erro de compilação, pois somente a classe PessoaFisica possui este método:
Durante a compilação teremos o seguinte erro informando que a classe material.polimorfismo.Pessoa não possui o método public void setCpf(long cpf):
mesmo o objeto sendo do tipo PessoaFisica, quando chamamos um método através da classe Pessoa, só podemos chamar os métodos que existem na classe Pessoa.
Durante a execução do programa, a JVM verifica qual a classe de origem do objeto e chama o método desta classe.
Para podermos atribuir o valor para CPF ou CNPJ, é preciso ter variáveis do tipo PessoaFisica e PessoaJuridica. No exemplo a seguir as variáveis são do tipo PessoaFisica e PessoaJuridica, elas serão guardadas dentro de um vetor de Pessoa:
Agora quando executarmos este programa tem a seguinte saída:
Se criarmos variáveis do tipo PessoaFisica ou PessoaJuridica, atribuirmos os valores para nome e cpf ou cnpj, depois disso podemos fazer variáveis do tipo Pessoa terem referencia para o mesmo objeto que as variáveis do tipo PessoaFisica e PessoaJuridica, por exemplo:
Na linha 18 foi criado uma variável pessoa1 do tipo Pessoa que recebe um objeto do tipo PessoaFisica.
Na linha 19 foi criado uma variável pessoa2 do tipo Pessoa que recebe um objeto do tipo PessoaJuridica.
Quando executarmos este programa tem a seguinte saída:
Dessa vez o valor do cpf e cnpj são impressos, pois foram previamente preenchidos.
Casting (conversão) de objetos
Vimos anteriormente que uma Pessoa (super classe) nem sempre É UMA PessoaFisica (subclasse), mas quando estamos trabalhando com uma super classe e temos a certeza de qual o tipo de subclasse ele está representando podemos fazer o casting de objetos, para guardar o objeto em sua classe, funciona de forma similar ao casting de atributos primitivos.
No exemplo a seguir, vamos criar duas variáveis do tipo Pessoa com objetos do tipo PessoaFisica e PessoaJuridica, depois vamos também criar uma variável do tipo Object (que é a super classe de todas as classes) e guardar nela um objeto do tipo String.
Na linha 18 estamos fazendo um casting de Pessoa para PessoaFisica. Na linha 21 estamos fazendo um casting de Pessoa para PessoaJuridica. Na linha 24 estamos fazendo um casting de Object para String.