scala - sencillos - sobrecarga de operadores en java
Scala: método / sobrecarga del operador (3)
No ha especificado el operador binario +, ha especificado el operador unario +.
Entonces, en lugar de:
def +(that: Int): Rational =
+(new Rational(that, 1))
Necesitas escribir esto:
def +(that: Int): Rational =
this +(new Rational(that, 1))
El siguiente ejemplo es del libro ''Programación en Scala''. Dada una clase ''Racional'' y la siguiente definición de método:
def add(that: Rational): Rational =
new Rational(
this.numer * that.denom + that.numer * this.denom,
this.denom * that.denom
)
Puedo sobrecargar con éxito el método add con una versión de conveniencia que toma un argumento Int, y hace uso de la definición anterior :
def add(that: Int): Rational =
add(new Rational(that, 1))
Sin problemas hasta ahora.
Ahora, si cambio el nombre del método a un nombre de estilo de operador:
def +(that: Rational): Rational =
new Rational(
this.numer * that.denom + that.numer * this.denom,
this.denom * that.denom
)
Y sobrecarga así:
def +(that: Int): Rational =
+(new Rational(that, 1))
Obtengo el siguiente error de compilación:
(fragment of Rational.scala):19: error: value unary_+ is not a member of this.Rational
+(new Rational(that, 1))
^
¿Por qué el compilador busca una versión única del método + ?
En Scala, cualquier construcción del tipo +x , -x , ~x y !x se transforma en un método llamado x.unary_+ , etc. Esto es parcialmente para permitir la sintaxis similar a Java de tener !b como la negación del boolean b , o -x como la negación del número x .
Por lo tanto, el fragmento de código +(new Rational(that, 1)) se traduce en (new Rational(that,1)).unary_+ , y como Rational no tiene este método, se obtiene un error de compilación. ¡Obtendrá este error solo si su función se llama + , - , ~ o ! ya que estos son los únicos caracteres que Scala permite como operadores unarios. Por ejemplo, si llama a su función @+ , el código compila muy bien.
Sin embargo, sugeriría escribir la función de agregar anulada como:
def +(that: Int): Rational =
this + (new Rational(that, 1))
Este código muestra mejor la intención de su función: agrega un nuevo Rational construido a partir de un entero como numerador y 1 como denominador a this . Esta manera de escribir se traduce en this.+(new Rational(that, 1)) , que es lo que quiere, invocando la función + en this .
Tenga en cuenta que puede usar la notación infija, sin embargo, se llama a la función. Por ejemplo, si cambia el nombre nuevamente para add , aún puede mantener la definición como:
def add(that: Int): Rational =
this add (new Rational(that, 1))
Si llamas + con this explícitamente, debería funcionar
def +(that: Int): Rational = this.+(new Rational(that, 1))
Scala permite definir operadores unarios que se pueden usar en notación de operador de prefijo. Por ejemplo, puede usar + como un operador de prefijo para lograr lo mismo:
def unary_+: Rational = this.+(new Rational(that, 1))
val a = new Rational(3,2)
val b = +a
Sin this explícito en su ejemplo, el compilador cree que está utilizando el operador unario + que no está definido.