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.