Link sobre Polimorfismo em Java

30 respostas
Andre_Fonseca

Oi

Segue um link interessante explicando polimorfismo em Java.
Duas coisas importantes que eu concordo e que causam muita confusão

[list]polimorfismo nada mais é do que a chamada do método sendo executada de formas diferentes, o que depende do objeto chamador[/list]
[list]para termos polimorfismo não necessariamente precisamos de herança, podemos ter o mesmo comportamento usando interfaces[/list]

Sei que já foi muito batido esse assunto aqui, mas acho que quanto mais discussão melhor, o que acham? :slight_smile:

30 Respostas

adriano_si

A palavra Herança, foi o que me matou por muito tempo para entender Polimorfismo em Java… não sei se é a mais adequada para explicar o que conhecemos como “HERANÇA”… acho que poderiam arranjar outro conceito melhor… mas pelo jeito a JAVA “Herdou” isso do C++, hehehehe

Perfeito o Link pra quem quer ter uma visão inicial e clara do conceito…

Falows :wink:

Andre_Fonseca

não é a toa que a Katty vive repetindo no livro Head First

Java NÃO é C++ :slight_smile:

adriano_si

hehehehe… pior…

O conceito de “herdar” pra mim, é bem diferente do que realmente ocorre quando nossa classe possui uma superclasse (ou seja, sempre)… mas como eu acho que não há uma palavra que defina o que realmente ocorre HERANÇA entrou por tabela…

Blz :slight_smile:

Lavieri

não li o artigo… então não sei bem o que ele quis dizer com

vou ler agora… mas c ele kiz dizer, que sobrecarga tem a ver com polimorfismo não esta correto… portanto o polimorfismo em se, não depende do objeto chamador, depende do objeto que esta sendo chamado… ou seja… vc tem um objeto, chama um método dele… e a depender da forma dentro do objeto, um comportamento diferente é executado…

vou ler, e depois entender o q ele kiz dizer e volto a falar

EDIT.: agora eu li, e realmente é muito bom o artigo, e totalmente coerente… mostra corretamente cada ponto… boa leitura a quem for ler

M

Perfeito … eu no início confundia mto polimorfismo com sobrecarga de métodos (na verdade até hj as vezes me enrolo um pko) … Mas quando vi acho q em um livro qualquer um exemplo do q eles denominaram polimorfismo dinâmico (pra mim o verdadeiro polimorfismo) q necessitava do uso d interfaces, fiquei deslumbrado com o potencial do verdadeiro polimorfismo … mto massa … por essas e outras q OO é massa … não q outros paradigmas não possam ser melhores … mas não é a toa q OO está aí até hj …

Andre_Fonseca

oi

pois é, ao invés de

melhor

:slight_smile:

Lavieri

com essa segunda frase fica bem + claro ^^

abraços

adriano_si

Nome mais bonitinho e enfeitado para POLIMORFISMO… não vejo um como estático, por isso, só polimorfismo já basta… hehehehe

Falows :wink:

Lavieri

eu so não concordo muito que o polimorfismo seja apenas na chamada do método… os tipos das variáveis em java tb são polimorficos, e é por isso que os métodos podem ser polimorficos, pois se não pudessomos passar varias formas para uma única variável tipada, não teriamos como chamar um método polimorficamente

leandronsp

Acho que o polimorfismo é além de uma “chamada de método”. É um grau de abstração perto de se imaginar oq é real: é o ato de um objeto tomar várias formas.
Essas várias formas são seus comportamentos em um determinado escopo. Esses comportamentos são por consequencia os metodos.

E Java, em tempo de compilação, “olha” para os tipos dos objetos. E executa o comportamento implementado nesses tipos.
Abraços pessoal, e nos vemos domingão no Falando em Java!

Lavieri

leandronsp:
Acho que o polimorfismo é além de uma “chamada de método”. É um grau de abstração perto de se imaginar oq é real: é o ato de um objeto tomar várias formas.
Essas várias formas são seus comportamentos em um determinado escopo. Esses comportamentos são por consequencia os metodos.

E Java, em tempo de compilação, “olha” para os tipos dos objetos. E executa o comportamento implementado nesses tipos.
Abraços pessoal, e nos vemos domingão no Falando em Java!

so uma correção, ele executa o comportamento, e olha para o tipo em tempo de execução, e não de compilação… em tempo de compilação, ele apenas “tenta” (e quanto fala tenta, é pq ele não garante, por isso existe os CastClassException em tempo de execução) garantir que vc “não tente enfiar uma bicicleta onde deveria existir um espelho por exemplo”.

Andre_Fonseca

a definição de polimorfismo, feita pela Monica Pawlan , que é criticada pelo professor, pode ser encontrada aqui, deve ter sido ela quem escreveu já que ela trabalha na SUN…

aqui temos uma outra definição

Segundo essa definição polimorfismo poderia ser implementado usando overload ou overriding - multiple methods having the same name

aqui tem outra definição, segundo a qual podemos ter tres tipos de implementação

[list]overloading[/list]
[list]overriding através de herança[/list]
[list]overriding através de interface[/list]

e ainda aqui tem outra definição mais completa ainda, segundo a qual temos 4 tipos de implementalção, coerção, overloading, parametrica e inclusão, a parametrica acho que seria o que o Lavieri quis dizer

resumindo, a definição de polimorfismo é clara, agora parece que não chegaram ainda a um consenso na forma de implementa-la… :smiley:

nada é tão simples como parece… rs

Andre_Fonseca

Lavieri:
leandronsp:
Acho que o polimorfismo é além de uma “chamada de método”. É um grau de abstração perto de se imaginar oq é real: é o ato de um objeto tomar várias formas.
Essas várias formas são seus comportamentos em um determinado escopo. Esses comportamentos são por consequencia os metodos.

E Java, em tempo de compilação, “olha” para os tipos dos objetos. E executa o comportamento implementado nesses tipos.
Abraços pessoal, e nos vemos domingão no Falando em Java!

so uma correção, ele executa o comportamento, e olha para o tipo em tempo de execução, e não de compilação… em tempo de compilação, ele apenas “tenta” (e quanto fala tenta, é pq ele não garante, por isso existe os CastClassException em tempo de execução) garantir que vc “não tente enfiar uma bicicleta onde deveria existir um espelho por exemplo”.

seria isso?

M

Então eu sempre tive o seguinte:

Dada a Classe Soma a seguir:
public class Soma {

  public int Soma(int x, int y) {
    return x+y;
  }

  public String Soma(String x, String y) {
    return x+y;
  }

  public double Soma(double x, double y) {
    return x+y;
  }
}
tem-se a Classe Main
public class Main {

    public static void main(String[] args) {
        Soma soma = new Soma();
        double d = soma.Soma(0.5, 0.5);
        int i = soma.Soma(10, 10);
        String string = soma.Soma("Plataforma", "Java");
        System.out.println(d); //imprime 1.0
        System.out.println(i); // imprime 20
        System.out.println(string); //imprime Plataforma Java
    }
}

Neste caso eu teria sobrecarga de método no método soma, ou polimorfismo estático (o polimorfismo dá-se em tempo de compilação)

No seguinte exemplo, polimorfismo dinâmico (o polimorfismo dá-se em tempo de execução), com o uso de Interface
public interface Operacao {

   int Calcular(int v1, int v2);

}
public class Soma implements Operacao {

    public int Calcular(int v1, int v2) {
        return v1+v2;
    }
}
public class Subtrair implements Operacao {

    public int Calcular(int v1, int v2) {
        return v1-v2;
    }
}
public class Conta {

    private static void mostrarResultado(Operacao op, int v1, int v2) {
        int resultado = op.Calcular(v1, v2);
        System.out.println(resultado);
    }

    public static void main(String[] args) {
        Soma soma = new Soma();
        Subtrair subtrair = new Subtrair();
        Conta.mostrarResultado(soma, 30, 20); //imprime 50
        Conta.mostrarResultado(subtrair, 30, 20); //imprime 10
    }
}

Basicamente é assim q eu entendo polimorfismo hj ... seria + ou - isso??

Andre_Fonseca

oi

o artigo utiliza a definição de 4 tipos de polimorfismo, como falei, coercion, overloading, parametric, inclusion

os dois primeiros tipos o autor considera polimorfismo ad-hoc, ou non-universal, algo como não verdadeiro ou simulado
os dois ultimos o autor considera como polimorfismo universal ou verdadeiro

Overloading polymorphism occurs when a child class overrides the method implementation of the parent class
Inclusion polymorphism occurs if a child class inherits its method substance from the base or parent class.
Inclusion polymorphism exists when several subclasses use the method of the superclass (parent) to perform whatever action is required. Overloading polymorphism exists when each subclass defines its own method of action, either because the parent class has declared the method abstract, or because it simply wishes to provide special processing.

Ou seja, a diferença entre os dois é que no overloading vc reescreve o método do pai..

Parametric polymorphism occurs when a class or classes implement methods that are the same in signature except for the parameters passed to the method.
Coercion polymorphism occurs when a primitive or object type is cast or "coerced" into being another primitive type or object type.

Parametric corresponde a definição do tutorial da SUN

Coercion seria algo parecido com o que ocorre quando fazemos

double d = 1.0 +2;

String s = "2" + 0;

acho que é o tipo mais dificil de polimorfismo de se definir

para as definições de tipos usei esta referência

t+

Andre_Fonseca

Mak,

Pelo que eu entendi, lendo as referências que passei, os exemplos que colocou seriam polimorfismo do tipo inclusion e overloading…

t+

Lavieri

eu discordo.. em partes... hehehe

public class Main {  
  
    public static void main(String[] args) {  
        Soma soma = new Soma();  
        double d = soma.Soma(0.5, 0.5);  
        int i = soma.Soma(10, 10);  
        String string = soma.Soma("Plataforma", "Java");  
        System.out.println(d); //imprime 1.0  
        System.out.println(i); // imprime 20  
        System.out.println(string); //imprime Plataforma Java  
    }  
}

neste exemplo ai... o único lugar onde há polimorfismo é no System.out.println(string) ...

neste lugar onde, vc tem a forma String sendo enviada para um lugar onde espera-se uma forma Object... é valido, e logico que funciona ... ai há sim o polimorfismo pq esse método aceita varias formas...

quanto aos métodos somas.... não há polimorfismo... o fato é que existem varias sobrecagas de método... e isso em se, não é polimorfismo, é apenas um coincidencia de nomes, o que é permitido.... cada objeto vai para o seu método adequado a ele... porem nada de polimorfismo esta ocorrendo... os métodos estão indo para onde deviam ir...

este seu código é o mesmo que escrever...

somaInt(int,int)
somaDouble(double,souble)
somaString(String,String)

isso é muito diferente....

quando há polimorfismo é quano realmente aceita-se muitas formas.. por xemplo

System.out.println(Object) ... aceita qualquer forma de objetc...
esse código vai chamar o método .toString() de object.... e idependente da implementação, ele vai chamar o método correto, do objeto que esta la dentor... isso sim é polimorfismo, pq vc usa MUITAS FORMAS.... esta assumindo que o método toString() tem uma forma diferente para cada objeto...

seu método soma não tem varias formas, ele apenas tem nomes coincidentes, com parametros distintos, é uma sobrecarga... e eles são idependentes um do outro... com sobriscrição não... quando vc sobrescreve... vc esta realmente eskecendo o antigo, e passando a exitir apenas o novo.... msmo que vc tente reduzir ou ampliar o objeto na hierarquia de classes

M

quanto aos métodos somas… não há polimorfismo… o fato é que existem varias sobrecagas de método… e isso em se, não é polimorfismo, é apenas um coincidencia de nomes, o que é permitido… cada objeto vai para o seu método adequado a ele… porem nada de polimorfismo esta ocorrendo… os métodos estão indo para onde deviam ir…

Sim … então sobrecarga de métodos != polimorfismo … tbm concordo … pq realmente são apenas métodos com nomes iguais …

Valeu as explicações … no outro exemplo onde utilizei Inteface aí há polimorfismo??

Lavieri

Mak:
quanto aos métodos somas… não há polimorfismo… o fato é que existem varias sobrecagas de método… e isso em se, não é polimorfismo, é apenas um coincidencia de nomes, o que é permitido… cada objeto vai para o seu método adequado a ele… porem nada de polimorfismo esta ocorrendo… os métodos estão indo para onde deviam ir…

Sim … então sobrecarga de métodos != polimorfismo … tbm concordo … pq realmente são apenas métodos com nomes iguais …

Valeu as explicações … no outro exemplo onde utilizei Inteface aí há polimorfismo??

um segundo é perfeito … o Operador é um exemplo de polimorfismo… é algo que relaiza operação, a operação em si, pode ser qualquer uma… o método não quer saber qual é operação, ele só pega e executa a operação do operador, com os argumentos passados, e ele faz isso idenpendente da forma do Operador… isso é sim polimorfismo… e é um bom exemplo

Andre_Fonseca

pelo que li overloading pode ser sim considerado polimorfismo, mas não polimorfismo verdadeiro…

mais opiniões

http://en.allexperts.com/q/Java-1046/method-overloading-polymorphism.htm

M

André Fonseca

Pelo visto há uma certa polêmica se sobrecarga d métodos pode ser considerado polimorfismo ou não …

Pelos links q vc passou realmente consideram como polimorfismo … mas eu particularmente fico com a opinião d q realmente não há polimorfismo pois apenas os métodos possuem o mesmo nome. No exemplo o método soma poderia ser somaInt, somaDouble e somaString, como bem disse o colega Lavieri …

Andre_Fonseca

oi

não acho polêmica, acho definições diferentes, qual a diferença entre considerar overloading falso polimorfismo ou não considerar polimorfismo?

na minha opinião o importante é vc saber o que é e principalmente quando usar e quais as vantagens vc pode obter :slight_smile:

M

No fundo acabam sendo apenas questões conceituais … denominações …

boa discussão esse seu tópico … :thumbup:

Lavieri
André Fonseca:
oi

não acho polêmica, acho definições diferentes, qual a diferença entre considerar overloading falso polimorfismo ou não considerar polimorfismo?

na minha opinião o importante é vc saber o que é e principalmente quando usar e quais as vantagens vc pode obter :)

acho que a diferença é pq não é polimorfico so isso... ^^ ... são apenas varios métos, com mesmo nome, mas não há nenhum morfismo entre eles... não existe relação entre os 3 métodos, de forma alguma, eles só estão ali escrito com mesmo nome, o que torna tudo mais simples na hora de escrever claro...

Quando vc fala em polimorfico é a capacidade de assumir que algo pode ser em diversas formas... assumir que sobrecarga é polimorfismo seria o mesmo que dizer

public class MinhaClasseMaluco {

   void addProduto(Produto p) {}
   void addFuncionario(Funcionario f) {}
   void addCebola(Cebola c) {}

}

ou seja, existe um polimorfismo ali ? pq o objeto é capaz de aceitar Cebolas, Funcionarios, Produtos ? a resposta vem instantaneamente a mente, pq é facil de ver, que não existe

não é pq eu dou um refactoring e transformo o código anterior nisso

public class MinhaClasseMaluco {

   void add(Produto p) {}
   void add(Funcionario f) {}
   void add(Cebola c) {}

}

que ele passa a ter muitas formas, ele continua sendo a mesma coisa, a unica diferença é que o método tem o mesmo nome....

e mais, por exemplo, o principio de assumir q o método aceita muitas formas simplismente some.... pq vc sempre saberá pra qual método estará enviando seu objeto, e assim ele não idepende da forma ...

.........

se existisse um único método add(), que aceitasse e interpretasse a forma, ai sim, estariamos diante de algo POLI Morfico...

porem não há nada de poli, ali, a não ser o fato de existirem 3 métodos

public class MinhaClasseMaluco {

   void add(Entidade e) {
     //se Cebola faz algo
     //se Funcionario faz outra coisa
     //se Produto faz mais outra coisa
   }

}

esse método acima, vai aceitar os 3 objetos anterior, quando vc manda pra ele, ele é polimorfico, pq ele aceita as 3 formas, vc quando manda pra ele, não escolhe qual forma mandar, ele vai se virar sozinho pra descobrir, e isso sim é polimorfismo....

ter q escolher um método, e só pq ele tem o mesmo nome, pra mim não caracterisa de forma alguma o polimorfismo

......

celso.martins
Lavieri:
public class MinhaClasseMaluco {

   void addProduto(Produto p) {}
   void addFuncionario(Funcionario f) {}
   void addCebola(Cebola c) {}

}

ou seja, existe um polimorfismo ali ? pq o objeto é capaz de aceitar Cebolas, Funcionarios, Produtos ? a resposta vem instantaneamente a mente, pq é facil de ver, que não existe

não é pq eu dou um refactoring e transformo o código anterior nisso

public class MinhaClasseMaluco {

   void add(Produto p) {}
   void add(Funcionario f) {}
   void add(Cebola c) {}

}

que ele passa a ter muitas formas, ele continua sendo a mesma coisa, a unica diferença é que o método tem o mesmo nome....
......

E podem ter implementações diferentes para cada tipo de argumento. Para funcionário você pode implementar de uma forma, para produto de outra e para cebola de outra.

Acho que a maior diferença seja com relação aos nomes e parâmetros serem exatamente iguais, no override. Um é sobrescrita o outro é sobrecarga. Em ambos os casos a implementação pode ser diferente. Acredito que pelo fato de na sobrecarga os parâmetros serem diferentes, eles são considerados métodos diferentes, enquanto que na sobrescrita, tudo é igual, o que muda é apenas a implementação, por isso é polimórfico.

M

1. public class MinhaClasseMaluco { 2. 3. void add(Entidade e) { 4. //se Cebola faz algo 5. //se Funcionario faz outra coisa 6. //se Produto faz mais outra coisa 7. } 8. 9. }

É apenas um exemplo claro, mas no caso ao invés d utilizar por exemplo if’s ou sentenças switch’s, algum padrão como strategy por exemplo deixaria o método mais … digamos assim … “polimórfico” ainda?? ou melhor, mais flexível eu acho …

Lavieri
celso.martins:
Lavieri:
public class MinhaClasseMaluco {

   void addProduto(Produto p) {}
   void addFuncionario(Funcionario f) {}
   void addCebola(Cebola c) {}

}

ou seja, existe um polimorfismo ali ? pq o objeto é capaz de aceitar Cebolas, Funcionarios, Produtos ? a resposta vem instantaneamente a mente, pq é facil de ver, que não existe

não é pq eu dou um refactoring e transformo o código anterior nisso

public class MinhaClasseMaluco {

   void add(Produto p) {}
   void add(Funcionario f) {}
   void add(Cebola c) {}

}

que ele passa a ter muitas formas, ele continua sendo a mesma coisa, a unica diferença é que o método tem o mesmo nome....
......

E podem ter implementações diferentes para cada tipo de argumento. Para funcionário você pode implementar de uma forma, para produto de outra e para cebola de outra.

Acho que a maior diferença seja com relação aos nomes e parâmetros serem exatamente iguais, no override. Um é sobrescrita o outro é sobrecarga. Em ambos os casos a implementação pode ser diferente. Acredito que pelo fato de na sobrecarga os parâmetros serem diferentes, eles são considerados métodos diferentes, enquanto que na sobrescrita, tudo é igual, o que muda é apenas a implementação, por isso é polimórfico.

acho q não é so isso.... quando vc sobrescreve... vc não avisa a ninguem, vc faz isso, e isso é automatico, ninguem precisa saber... tudo continua igual, vc trocou o seu modo de operar para aquele método. Se alguem tratar vc, como se vc fosse uma classe de um SuperTipo seu (mesmo que esse supertipo seja uma interface) ... ele vai continuar trabalhando igual... a diferença é na sua forma de agir...

O mesmo não ocorre com sobrecarga.... vc pode ate roubar um fluxo, que anteriormente iria para outro método, mas a outra classe vai sim ser avisa, tanto é verdade que ser por exemplo
//versao 1
public class Produto {
   private String s;
   public Produto(String s) { this.s = s;}
   pulbic boolean equals(Object o) {
      return o instanceof Produto && s.equals(((Produto)o).s);
   }
}
Veja que eu to usando o equals
public class MinhaClasseDesligada {
   public void doStuff() {
       Produto um = new Produto("alhos");
       Produto dois = new Produto("bugalhos");
       if (um.equals(dois))
         System.out.println("iguais");
       else
         System.out.println("diferentes");

   }
}

agora digamos q eu mude a minha classe Produto

//versao 2
public class Produto {
   private String s;
   public Produto(String s) { this.s = s;}
   pulbic boolean equals(Object o) {
      return o instanceof Produto && s.equals(((Produto)o).s);
   }
   public Integer equals(Produto o) { //<<== sobrecarga com retorno diferente
      return 1;
   }
}

é tão verdade que há aviso, que a classe MinhaClasseDesligada para de funcionar... pq um retorno que antes era boolean virou Integer... tudo bem que o fluxo passou a ser outro... mas o método é realmente outro... ele so tem o mesmo nome... mas não precisa nem ser a mesma coisa, nem retornar a mesma coisa.. ele simplismente pode ser algo totalmente diferente... que não tem nada a ver... e por isso n tem como conciderar polimorfismo

Andre_Fonseca

Hehe,

Pois é, já tiveram essa discussão aqui antes

Agora outra citação

As minhas conclusões

para entender polimorfismo em Java precisa entender a diferença entre dynamic e static binding

se pensarmos em OO overloading NÃO pode ser considerado polimorfismo

M

Porque deveria haver um consenso para implementar polimorfismo?

A ideia esta clara, o comportamento pode variar enquanto a interface seja a mesma, existem diferentes formas de implementar polimorfismo no nivel da linguagem, e outrar serao inventadas. Esse tipo de detalhe so importa pra quem quer se aprofundar no design de linguagens de programacao, é o seu caso?

Andre_Fonseca

sim, esse é o meu caso, sou bastante detalhista as vezes, o conceito de polimorfismo do Java foi meio que aproveitado do C++ onde você tem outros conceitos como funções virtuais, por isso talvez a confusão …
t+

Criado 19 de maio de 2009
Ultima resposta 21 de mai. de 2009
Respostas 30
Participantes 7