Sobrecarga de Operadores

Olá Pessoal.

Por que Java não tem sobrecarga de operadores.

Andei aprendendo Python recentemente e me parece um recurso bem util, existe alguma questão de design que faz com que eles não implementem ?

O que voces acham, tipo

ArrayList l1 = new ArrayList(3);
l1[0] = "A"
l2[1] = "B"
l3[2] = "C"

ou com mapas

Map m = new HashMap();
m["Nome"] = "Joao";

com um StringBuilder

StringBuilder b = new StringBuilder();
b += " Olá Mundo ";
b += new char[]{'A','B','C'};
b += true;
b += 123;

no caso substituindo os append.

ou então nas suas proprias classes

public class Caixa
{
     private ArrayList items = new ArrayList();

     public void __setitem__(index, valor){
          items[ index ] = valor;
     }

     public void __getitem__(index){
          return items[ index ] ;
     }

}

Enfim não daria mais produtividade ?

Falow a todos

Sobrecarga de operadores eh util pra um numero tao pequeno (porem extremamente frequente) de usos, que eu nao sei se vale a pena ser feature da linguagem.

Por outro lado, dah uma olhada no que o why_ fez no hpricot :wink:

Tem gente que acha que sim, tem gente que acha que não. Já foi discutido isso várias vezes.

Se quiser, vote aqui para ter operator overloading.

http://forum.java.sun.com/thread.jspa?threadID=624342&messageID=3550166

Até!

Seria muito bom para contornar o sofrível suporte a aritmética com datas do Java…

Pior que isso só regular expressions com o seu match tentando dar um match na string inteira e não apenas em qualquer parte dela…

O problema é: o que um código desses faz?

Carro c1 = new Carro(); Carro c2 = new Carro(); Carro c3 = c1 + c2
Soma os anos de fabricação, a capacidade dos tanques, a quilometragem rodada ou não tem nada a ver?
Flexibilidade e legibilidade andam em sentidos opostos. Não sei até que ponto isso vale a pena.

Chama o metodo public Carro +(Carro) da classe Carro, ueh. O que esse metodo faz depende da implementacao. :wink:

Sinceramente não concordo com o argumento de que overload de operadores podem deixar o código mais complicado ou afetaria a legibilidade. Tudo depende do programador, assim como ocorre com o nome de método. Eu poderia muito bem fazer um método chamado add() que multiplicasse ao invés de somar.
A possibilidade de operador sobrecarregado não seguir a semântica padrão não é maior que com os nomes dos métodos, mas em compensação se teria uma grande vantagem de simplificar a sintaxe em muitas construções.

Chama o metodo public Carro +(Carro) da classe Carro, ueh. O que esse metodo faz depende da implementacao. ;)[/quote]

Mas é isso que considero o problema: você precisa ver a implementação pra saber o que ele faz.

Tá, aí você poderia escolher um nome ruim. Mas, no caso do operador, não há nome algum. (Meu exemplo é meio tosco, é verdade).

Ou então ver o Javadoc, como em qualquer outro método. :wink:


public class Caixa
{

     /**
      * @param caixa a caixa que será adicionada.
      * @return uma nova caixa cujos itens são as somas dos itens desta         
      * caixa com a caixa de parametro. 
      */
     public Caixa +(Caixa caixa){
          Caixa caixa = new Caixa();
          caixa.setItens( this.itens.clone() + caixa.itens.clone() );
          return caixa;
     }
}

No caso o operador seria uma mera abreviação do metodo, para dar mais legibilidade, mais nada impediria voce de documenta-lo.

E se eu tivesse 2 classes com o “+” sobrecarregado com comportamentos diferentes? E se tivesse 20? E 200? Iria ficar lendo o javadoc de todas para saber o que o “+” faz em cada uma?

O Java querendo adotar um padrão e vocês querendo fugir de um comportamento comum.

Até!

[quote=maquiavelbona]E se eu tivesse 2 classes com o “+” sobrecarregado com comportamentos diferentes? E se tivesse 20? E 200? Iria ficar lendo o javadoc de todas para saber o que o “+” faz em cada uma?
[/quote]
exatamente a mesma coisa que tu tem que fazer com o metodo add de todas estas 20 ou 200 classes

[quote=maquiavelbona]E se eu tivesse 2 classes com o “+” sobrecarregado com comportamentos diferentes? E se tivesse 20? E 200? Iria ficar lendo o javadoc de todas para saber o que o “+” faz em cada uma?

O Java querendo adotar um padrão e vocês querendo fugir de um comportamento comum.

Até![/quote]

Não entendi, no caso assim como num metodo o operador do objeto à esquerda ia ser aplicado.

public class Caixa
{
   public Caixa +(Caixa c){
          Caixa caixa = new Caixa();
          caixa.setItens( c.getItens().clone(), this.getItens().clone() );
          return caixa;
   }
}

public class SuperCaixa extends Caixa
{
   public SuperCaixa +(SuperCaixa c){
          SuperCaixa caixa = new Caixa();
          caixa.setItens( c.getItens().clone(), this.getItens().clone() );
          return caixa;
   }
}

Exemplo de uso:

Caixa c1 = new Caixa();
SuperCaixa c2 = new SuperCaixa();

Permitido pois c2 é um tipo de caixa:

Caixa c3 = c1 + c2;

Daria erro pois nem toda caixa é uma SuperCaixa

SuperCaixa c4 = c2 + c1;

Colocar o nome dum método de add sendo que vai ter N métodos parônimos é deveras estúpido. Se você soma um carro com um carro, e um parafuso com um parafuso, os métodos, em tese, deveriam ser nomeados singularmente, pois os comportamentos são singulares. Senão, de nada adianta essa verborréia na convenção se você não faz uso dela. Se vais somar carros, supôe-se que seja algo do tipo addCar, se vai somar parafusos, addScrew ( ou suas variantes addAnotherScrew, addOneMoreScrew, addLotsOfScrews(List listScrews)), assim por diante.

Até!

Obs.: Desculpem o estúpido, não achei palavra melhor. Não se sintam ofendidos com meu vocabulário diminuto.

Aliás, somar carro com carro, para mim, é coisa de recuperadora de veículos. Faz sentido somar produtos a uma cesta. Se ambos fossem sobrecarregados com “+”, o comportamento do primeiro seria juntar dois carros, do segundo aglomerar produtos dentro de um cesta. Viu que complicação sendo que existe uma convenção de símbolos?

Até!

[quote=maquiavelbona]Aliás, somar carro com carro, para mim, é coisa de recuperadora de veículos. Faz sentido somar produtos a uma cesta. Se ambos fossem sobrecarregados com “+”, o comportamento do primeiro seria juntar dois carros, do segundo aglomerar produtos dentro de um cesta. Viu que complicação sendo que existe uma convenção de símbolos?

Até![/quote]

Mais isso de fazer sentido varia de acordo com a sua regra de negócios, não tem nada a ver com a linguagem.

Eu poderia ter um produto que ao ser somado com outro seria um produto composto. :wink:

tipo minha regra de negócios diria que posso comprar tanto um Saco de Arroz quanto juntar diversos produtos e virar um só

Produto cestaBasica = new Produto();

cestaBasica += new Produto("Arroz");
cestaBasica += new Produto("Macarrao");
cestaBasica += new Produto("Feijão");
cestaBasica += new Produto("Tamarindo");
cestaBasica += new Produto("Café");
cestaBasica += new Produto("Caviar");
//... etc.

Mas tudo isso para trocar um “add” por um “+”?
Não acho legal não.

Tem sempre gente reclamando por ai que java suporta coisas demais, por isso da complexidade.

Tem tanta gente estusiasmada com o RoR exatamente pela simplicidade do mesmo, agora por que vamos encher o java de “jeringonças”(não sei como se escreve isso), simplesmente para dar “maaaais uma” possibilidade de dinamizar o código porém sem ganho nenhum?

Então, vocês querem obscurecer essas formas díspares de trabalho com operadores comuns. Recai no que eu comentei sobre os métodos add parônimos. Dentro de um sistema, que pode virar um monstro no curto ou longo prazo, deixar livre essa escolha pode ( e em geral vai ) se tornar prejudicial a interpretação. Numa parte do código, o “+” mescla dois produtos, em outra “+” agrupa emails de um cliente, em outra incrementa o contador de visitas, em outra sobrepõe o endereço de entrega etc.

Com a verbosidade levantada para deixar o código mais legível, frente as reclamações das linguagens que usam nomes obscuros( ou alguém logo de primeira, só de bater o olho, já sabe o que faz array_uintersect_uassoc ) , sobrecarregar símbolos para supostamente deixar mais legível, tende a ficar paradoxal.

Até!

[quote=AndrewAguiar]Olá Pessoal.

Por que Java não tem sobrecarga de operadores.

[/quote]

A razão para isso é simplicidade e manutenção da linguagem.
Quando vc tem sobrecarga de operadores, na realidade vc pode implementar sublinguagens. Imagine que cada API de terceiros, por ai, criáva seus proprios operadores. Ia ser uma dor de cabeça…
Associação de operadores como é usado no Groovy parece mais interessante. Por exemplo, o sinal + pode ser usado por qq classe que implemente plus() e o sinal * por multiply() e variável[“string”]=a por put(“string”,a) e assim vai. Agora definir novos simbolos (como se faz no C) parece meio caminho andado para complicar demais as coisas.

Acho que simplesmente permitir a sobrecarga do operador ‘+’ no Java não iria mudar tanta coisa assim, como já foi falado, o método add() aparece atualmente em trocentas classes, dá no mesmo. A questão é que sobrecarga de operadores vai muito além do operador ‘+’ (digo isso porque quase toda a discussão neste tópico ficou focada neste operador). Se a feature de sobrecarga de operadores fosse aprovada no Java num molde semelhante ao que temos em C++, poderiamos sobrecarregar praticamente qualquer operador. Isso inclui:
++

/
*
[]

!=
&lt
&gt

e por ai vai.

Perceberam o nível de complexidade disso? Se deixar, vira uma zona fácinho, fácinho.
Eu não quero ficar comendo documentação, quero escrever código. Do mesmo modo que utilizar add() é ambiguo, utilizar sobrecarga de operador também é. Dá na mesma procurar na documentação de todas as classes que implementam uma interface que possui o método add() ou nas subclasses de uma classe que sobrecarrega o operador ‘+’.
enfim, uma bagunça…
Por outro lado, para tentar acabar com ambiguidade no nome de métodos, temos que tornar o Java cada vez mais verboso, com nomes de métodos que definam exatamente o comportamento esperado, para todas as classes. Eu acho que já escrevo demais para programar em Java…
Sinceramente não vejo muita solução para isso não. Vai de estilo de programar. Java não tem sobrecarga, ponto final. Quer sobrecarga, vai programar em C++. Mas também não reclama que Java é verboso… Temos que conviver com isso.

[quote=nbluis]Mas tudo isso para trocar um “add” por um “+”?
Não acho legal não.

Tem sempre gente reclamando por ai que java suporta coisas demais, por isso da complexidade.

Tem tanta gente estusiasmada com o RoR exatamente pela simplicidade do mesmo, agora por que vamos encher o java de “jeringonças”(não sei como se escreve isso), simplesmente para dar “maaaais uma” possibilidade de dinamizar o código porém sem ganho nenhum?

[/quote]

E por que fizeram o for-enhanced ? :smiley:

Teoricamente tudo que voce faz no for-enhaced voce ja conseguia fazer antes com o for normal.

para dar agilidade.

E pelo que sei Ruby apesar da simplicidade tem sobrecarga de operadores.

também concordo que definir simbolos novos é meio suicida, mais poderia ser assim voce pode sobreescrever somente os operadores já existentes operadores…