Existe polimorfismo sem herança

E ai chará,também me chamo danilo e ja tinha posto um topico a respeito deste assunto.

http://www.guj.com.br/posts/list/93258.java#499498

  • falando serio,olha o link q mandei,há um certa divergencia de pensamentos e conceitos,sendo que segundo alguns os proprios autores da serie “Use a cabeça” cometem equivoco ao falarem de polimorfismo e herança

[quote=luistiagos][quote]
a diferença é que no var-args vc nao informa quantos paramentos devem ser passados no metodos, vc pode passar de 1 à …
[/quote]

eu tbm posso ter um array de 1 a … e passa-lo para o metodo veja meu exemplo acima…

para vc ver como eu não sou mentiroso tente compilar isto e veja o que vai dar:


class X {

   public void fazAlgo(int ...arr) {

   }

    public void fazAlgo(int []arr) {

   }

}

se var-args é um tipo especial de sobrecarga isto vai compilar e rodar perfeitamente…

e sobre heraça e polimorfismo ngn aqui disse em momento algum que herança == poliformfismo…
a questão era se existe polimorfismo sem herança… a unica maneira plausivel para isto em java é a sobrecarga… de fato em minha primeira resposta a este post esqueci da sobrecarga que usa o conceito de polimorfismo…
[/quote]

eu sei apenas abordei um ponto amplo entre os dois para ficar claro… polimorfismo e herança no inicio sao confusos para quem vi de primeiro… e a questao do array tinha esquecido hehe!
Não lembro perfeitamente pq a sun criou var-args a kathy ate explica em um trecho do seu livro… mais nao lembro!

No caso do extends você não estará mentindo. Mesmo que por enquanto a classe A seja funcionalmente igual a uma interface, não é isso que a relação diz. Diz que B é um A. Portanto, eles compartilham o mesmo escopo, definições e conceito. Num sistema, também significa que vc está autorizado a incluir propriedades e métodos em A futuramente, e B os terá.

Agora, se vc fizer isso:

[code]interface A {
void doIt();
}

class B implements A
{
void doIt() { System.out.println(“Do it!”); }
}[/code]

Você não está falando que B é um A. Mas que B implementa o contrato definido por A. Esta é uma relação apenas comportamental, não envolve tipos.

É claro que outras coisas tornam essa definição confusa, como poder usar instanceof nos dois casos. Mesmo muitos livros tratam o assunto indistintamente. Mas estavamos comentando a respeito do conceito, não da implementação. Como eu cite, no caso do groovy, não haveria aquela interface. Você só teria em alguma momento:

def someMethod(objectWhoCanDoIt) { objectWhoCanDoIt.doIt() }

O objectWhoCanDoIt não precisa implementar nada. Bastaria ter na sua assinatura um método doIt(). Agora, a interface ainda existe. Você provavelmente terá definido um documento em algum lugar com coisas do tipo:

/** Do itable é um objeto que pode fazer doIt(). 
   O doIt() é uma ação personalizada, tal qual o run() dos Runnables Java.
*/

O que não deixa de ser uma interface, um contrato comportamental. Mas implementada de forma diferente, numa linguagem diferente.

bem então neste exemplo:


interface A {
  final static int x = 4;
}

a classe que implementar esta interface tera herdado a constante x…
dai neste ponto o argumento:
Mas que B implementa o contrato definido por A…
neste ponto B não ira implementar nenhum contrato definido por A ele ira herdar a constante de A…
e se for ver em C++ por exemplo… não existem interfaces e permite-se herança multipla… isto ao meu ver e uma falha na OO… porem isto ja é coisa para outra Thread… porem posso simular herança multipla do C++ com interfaces… por isto creio que no fundo mas bem no fundo por baixo dos panos em java interface na verdade emprega os conceitos de herança…

e a mesma questão que os var-args… nos var-args vc ve a coisa assim:

public void doIt(int... x) {

}

porem a vm enxerga isto:

public void doIt(int []x) {

}

o mesmo acontesse com as interfaces…
vc as ve assim:

interface face {
   public void doIt();
}

class A implements face {
     public void doIt(){}

}

porem a vm enxerga assim:


abstract class face {
   public abstract void doIt();
}

class A extends face {
   public void doIt(){}
}

porem é claro vc dificilmente vai ver em um livro detalhes da vm, do compilador e coisas assim “debaixo dos panos…” por questão de didatica…

“a única coisa que muda” é a forma da chamada. Dai ser um tipo de polimorfismo ( várias formas de chamada)

[quote] var-args é apenas um recurso da linguagem feito para simplificar a chamada do metodo não precisando criar um array para passar os argumentos porem isto é feito de qualquer modo mas implicitamente… dizer que var-args é uma especie de sobrecarga não é verdade pois:
foo(new int[]{1,2}) e foo(new int[]{1,2,3}) e foo(new int[]{1,2,3,4}) não são overloads e sim apenas um metodo que recebe um array de inteiros… [/quote]

  1. “Recurso de Linguagem” é um termo sem significado aqui. Se formos por ai tudo são recursos da linguagem.
  2. Embora podendo ser açucar sintático implica em uma forma extra de fazer uma chamada ao método o que sigifica que ha um polimorfismo. (Afinal vc concordo com generics serem um tipo de polimorfismo e na realidade tb não passam de truque de compilação)
  3. É claro que podemos entender var args como um a forma de sobrecarga porque é equivalente a escrever isto :

[code]public void metodo ( int a){
metodo ( new int[]{a});
}

public void metodo ( int a, int b){
metodo ( new int[]{a,b});
}

public void metodo ( int a, int b , int c){
metodo ( new int[]{a,b,c});
}

public void metodo ( int[] params){

}[/code]

A diferença é que vc só escreve um método e o compilador “escreve os outros” ( na realidade ele altera o codigo para não ter que declarar os métodos, mas tudo bem). Para todos os efeitos o codigo se comporta como se todos os métodos existissem lá. Isso permite chamar o mesmo métodos de formas diferentes :

metodo (1,2 );
metodo (1,2,3 );
metodo ( new int[]{1,2,3} );

O que significa que int … params é diferente de int[] params “por fora” mas são de alguma forma compatíveis e portanto são formas diferentes da mesma coisa. Ou seja, ( int … params) representa várias assinaturas de métodos. Várias formas de chamar o mesmo método.

só pra constar, em portugues do brasil, o termo é “sobrescrever” / “sobrescrita”

http://dic.busca.uol.com.br/result.html?q=sobrescrever&group=0&t=10

exatamente ele altera as chamadas para não precisar sobrescrever os metodos ou seja ele faz algo para não precisar usar sobscrita que é algo que usa polimorfismo… e outra em uma sobscrita classica eu teria isto:


public void doIt(int a) {
    //aqui tenho um inteiro
}

public void doIt(int a, int b) {
   //aqui eu tenho 2 inteiros
}

public void doIt(int ...a)  {
  aqui eu tenho um ARRAY de inteiros
}

portanto em uma sobrecarga classica eu poderia usar o primeiro metodo com apenas um tipo primitivo inteiro…
o segundo 2… e o terceiro um objeto array com n inteiros… o conceito de polimorfismo é varias formas e não varias chamadas diferentes… se eu fizer isto:

class A {
public void doIt(int a, int b) {
    System.out.println("sem var-args");
}

public void doIt(int ...a) {
   System.out.println("com var-args");
}

public static void main(String ...args) {
  A a = new A();
  a.doIt(1,2); 
}
}

compila que vc vai ver a saida…
onde a polimorfismo ai? a na sobrecarga entre o var-args e o que passa 2 primitivos… um metodo tem um comportamento, uma forma e o outro outra totalmente diferente…

var-args somente é polimorfico na chamada… assim como meu array de inteiro é polimorfico na chamada… pois posso criar varios arrays passando n elementos diferentes… isto são formas diferentes…

porem o conceito de polimorfismo não extende somente a chamada… e sim o comportamento do metodo…

[quote=Sergio Lopes]só pra constar, em portugues do brasil, o termo é “sobrescrever” / “sobrescrita”

http://dic.busca.uol.com.br/result.html?q=sobrescrever&group=0&t=10
[/quote]

É bom saber. Da ultima vez que procurei não registravam o termo. Nem nos dics do brasil nem de pt.
Agora aparece em ambos.

[quote=luistiagos][quote]
A diferença é que vc só escreve um método e o compilador “escreve os outros” ( na realidade ele altera o codigo para não ter que declarar os métodos, mas tudo bem). Para todos os efeitos o codigo se comporta como se todos os métodos existissem lá. Isso permite chamar o mesmo métodos de formas diferentes :
[/quote]

exatamente ele altera as chamadas para não precisar sobrescrever os metodos ou seja ele faz algo para não precisar usar sobscrita que é algo que usa polimorfismo… e outra em uma sobscrita classica eu teria isto:
[/quote]

Cara, assim a discussão não é séria. Vc está misturando sobrescrever com sobescrever (que não existe) com sobrecarga…

Bom, isso é o que vc acha…
Se vc quiser pensar que polimorfismo apenas no que se refere a herança e pensar que tudo o resto ( sobrecarga, sombreamento, var-args, auto-boxing, generic-types, etc…) são funcionalidades da linguagem vá em frente. O problema não é meu. É todo seu.

Agora se vc quiser parar dois minutos e pensar o que significa escopo, “poli-morfismo” e herança vai chegar à conclusão que sim se pode entender “funcionalidades da linguagem” como polimorfismo. A escolha é sua.

Em seu exemplo:

public void metodo ( int a){   
    metodo ( new int[]{a});   
}   
  
public void metodo ( int a, int b){   
    metodo ( new int[]{a,b});   
}   
  
  
public void metodo ( int a, int b , int c){   
    metodo ( new int[]{a,b,c});   
}   
  
public void metodo ( int[] params){   
  
} 

vc pode muito bem observar que o unico metodo que tem um comportamento é o que recebe []params o resto não faz nada apenas redireciona para este metodo… ou seja chamando qualquer um deles vc estara chamando o mesmo metodo… e isto não é polimorfismo por sobrescrita… seria se cada um desses metodos tivessem uma função/comportamento distinto…
aliais isto é um exemplo de pog pois todos estes metodos podem ser substituido por um so apenas passando um array na chamada dele…

Pelo que eu sei e aprendi de Orientação a Objeto, polimorfismo só existe com Herança.

Os casos sem herança são os de vc sobrepor um método.

[quote=luistiagos]vc pode muito bem observar que o unico metodo que tem um comportamento é o que recebe []params o resto não faz nada apenas redireciona para este metodo… ou seja chamando qualquer um deles vc estara chamando o mesmo metodo… e isto não é polimorfismo por sobrescrita… seria se cada um desses metodos tivessem uma função/comportamento distinto…
aliais isto é um exemplo de pog pois todos estes metodos podem ser substituido por um so apenas passando um array na chamada dele…[/quote]

É polimorfismo por sobrescrita! A implementação dos métodos é irrelevante! Até porque a orientação a objetos tem como um de seus objetos ocultar a implementação para o mundo de fora.

E isso não é POG! POG é deixar que rotinas de conversão de tipos, praticamente iguais, fiquem espalhados por todo o sistema, sempre antes de chamar o método do objeto.

acho que vc não leu meu post…
eu não disse que polimorfismo apenas se refere a herança… eu disse que ele não se refere a var-args…

correto… porem este é outro conceito da OO o encapsulamento… estamos aqui falando sobre polimorfismo e var-args…


public void foo() {
   //faz algo
}

public void foo(int x) {
   foo();
}

isto ai em cima é pog… pois o metodo que recebe o x como argumento não faz porra nenhuma alem de chamar
o outro metodo foo() ou seja isto foo(4) é substituido por isto: foo()

agora isto:


public void foo() {
   //faz algo
}

public void foo(int x) {
  //faz outra coisa que não faz em foo 
  foo();
}

não é pog pois foo(x) faz outra coisa e depois chama foo

[quote=luistiagos]Em seu exemplo:

public void metodo ( int a){   
    metodo ( new int[]{a});   
}   
  
public void metodo ( int a, int b){   
    metodo ( new int[]{a,b});   
}   
  
  
public void metodo ( int a, int b , int c){   
    metodo ( new int[]{a,b,c});   
}   
  
public void metodo ( int[] params){   
  
} 

vc pode muito bem observar que o unico metodo que tem um comportamento é o que recebe []params o resto não faz nada apenas redireciona para este metodo… ou seja chamando qualquer um deles vc estara chamando o mesmo metodo… e isto não é polimorfismo por sobrescrita…
[/quote]

Pois não é. Nem deveria ser. var agrs é um tipo especial de polimorfismo por sobrecarga

[quote]
aliais isto é um exemplo de pog pois todos estes metodos podem ser substituido por um so apenas passando um array na chamada dele…[/quote]

Não , não podem. Por isso que precisamos de var-args

Isto :

metodo ( new int[]{1});  
metodo ( new int[]{1,2});  
metodo ( new int[]{1,2,3});

Não é polimorfismo. É o uso normal do método com arrays literais.

[quote]Polimorfismo

Polimorfismo é o princípio pelo qual duas ou mais classes derivadas de uma mesma superclasse podem invocar métodos que têm a mesma identificação (assinatura) mas comportamentos distintos, especializados para cada classe derivada, usando para tanto uma referência a um objeto do tipo da superclasse. A decisão sobre qual o método que deve ser selecionado, de acordo com o tipo da classe derivada, é tomada em tempo de execução, através do mecanismo de ligação tardia.

No caso de polimorfismo, é necessário que os métodos tenham exatamente a mesma identificação, sendo utilizado o mecanismo de redefinição de métodos. Esse mecanismo de redefinição não deve ser confundido com o mecanismo de sobrecarga de métodos.

O uso de polimorfismo em Java é ilustrado através de um exemplo. Através desse exemplo introduzem-se os conceitos relacionados de upcasting e a motivação para a definição de métodos abstratos.

É importante observar que, quando polimorfismo está sendo utilizado, o comportamento que será adotado por um método só será definido durante a execução. Embora em geral esse seja um mecanismo que facilite o desenvolvimento e a compreensão do código orientado a objetos, há algumas situações onde o resultado da execução pode ser não-intuitivo, como ilustra esse exemplo que usa polimorfismo em construtores.

Fonte: http://www.dca.fee.unicamp.br/cursos/PooJava/polimorf/index.html[/quote]

Volto a repetir não existe polimorfismo sem herança.

Exemplo de polimorfismo:

[code]abstract class Polimorfismo {
public void imprime(){
System.out.println(“Teste”);
}
}

class PolimorfismoA extends Polimorfismo{
public void imprime() {
System.out.println(“PolimorfismoA”);
}
}
class PolimorfismoB extends Polimorfismo{
public void imprime() {
System.out.println(“PolimorfismoB”);
}
}[/code]

[code]public class Main {

/**
 * @param args
 */
public static void main(String[] args) {
	Polimorfismo exemplo = new PolimorfismoA();
	exemplo.imprime();
	exemplo = new PolimorfismoB();
	exemplo.imprime();
}

}[/code]

não vou repetir se quiser pensar que var-args é um tipo de sobrecarga pense… pq na verdade sobrecarga != var-args

[quote=luistiagos][quote]
Bom, isso é o que vc acha…
Se vc quiser pensar que polimorfismo apenas no que se refere a herança e pensar que tudo o resto ( sobrecarga, sombreamento, var-args, auto-boxing, generic-types, etc…) são funcionalidades da linguagem vá em frente. O problema não é meu. É todo seu.
[/quote]

acho que vc não leu meu post…
eu não disse que polimorfismo apenas se refere a herança… eu disse que ele não se refere a var-args…

[/quote]

Ok, então eu reformulo:

Se vc quiser pensar que polimorfismo apenas no que se refere a herança, sobrecarga, sombreamento, auto-boxing, generic-types, etc… e pensar que var-args são funcionalidades da linguagem vá em frente. O problema não é meu. É todo seu.

Mas já agora porque auto-boxing pode ser polimorfismo e não uma " funcionalidade da linguagem" ?
A mesma pergunta é válida para sobrecarga , sombreamento , generic-types, etc…
O que var args tem que estes não têm , ou vice-versa ? (perguntas retóricas)

[quote=king_of_gods]
Volto a repetir não existe polimorfismo sem herança.[/quote]

Tudo bem. Então sombreamento, sobecarga, tipos genericos , auto-boxing são tudo tipos de quê ? “funcionalidades da linguagem” ?
Ok. Mas nesse caso herança tb é apenas uma “funcionalidade da linguagem”. Assim não vamos a lado nenhum…

[quote=sergiotaborda][quote=king_of_gods]
Volto a repetir não existe polimorfismo sem herança.[/quote]

Tudo bem. Então sombreamento, sobecarga, tipos genericos , auto-boxing são tudo tipos de quê ? “funcionalidades da linguagem” ?
Ok. Mas nesse caso herança tb é apenas uma “funcionalidade da linguagem”. Assim não vamos a lado nenhum… [/quote]

O que vcs estão batendo cabeça é:

POLIMORFISMO - é uma coisa, SOBRECARGA é outra coisa, SOMBREAMENTO é outra coisa ainda. Todos são tipos de construção de métodos na Orientação a Objeto.

Herança não é funcionalidade da linguagem, herança é uma caracteristica que qualquer linguagem orientada a objeto tem que permitir.

Orientação a Objeto não é dá linguagem JAVA , é um conceito q o JAVA utiliza. Lembre-se disso.