unarios sobrecarga sencillos operadores metodos funciona ejercicios ejemplos como clases scala

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.