Este ejemplo esta tomado de Rosetta Code (Complex Class in Groovy):
generaciondecodigos@nereida:~/src/groovy/overloading$ cat -n Complex.groovy 1 class Complex { 2 final Number real, imag 3 4 static final Complex I = [0,1] as Complex 5 6 Complex(Number real) { this(real, 0) } 7 8 Complex(real, imag) { 9 this.real = real; this.imag = imag 10 } 11 12 Complex plus (Complex c) { [real + c.real, imag + c.imag] as Complex } 13 14 Complex plus (Number n) { [real + n, imag] as Complex } 15 16 Complex minus (Complex c) { [real - c.real, imag - c.imag] as Complex } 17 18 Complex minus (Number n) { [real - n, imag] as Complex } 19 20 Complex multiply (Complex c) { [real*c.real - imag*c.imag , imag*c.real + real*c.imag] as Complex } 21 22 Complex multiply (Number n) { [real*n , imag*n] as Complex } 23 24 Complex div (Complex c) { this * c.recip() } 25 26 Complex div (Number n) { this * (1/n) } 27 28 Complex negative () { [-real, -imag] as Complex } 29 30 /** the complex conjugate of this complex number. 31 * Overloads the bitwise complement (~) operator. */ 32 Complex bitwiseNegate () { [real, -imag] as Complex } 33 34 /** the magnitude of this complex number. */ 35 // could also use Math.sqrt( (this * (~this)).real ) 36 Number abs () { Math.sqrt( real*real + imag*imag ) } 37 38 /** the complex reciprocal of this complex number. */ 39 Complex recip() { (~this) / ((this * (~this)).real) } 40 41 /** derived angle θ; (theta) for polar form. 42 * Normalized to [0, 2 * π] */ 43 Number getTheta() { 44 def theta = Math.atan2(imag,real) 45 theta = theta < 0 ? theta + 2 * Math.PI : theta 46 } 47 48 /** derived magnitude ρ; (rho) for polar form. */ 49 Number getRho() { this.abs() } 50 51 /** Runs Euler's polar-to-Cartesian complex conversion, 52 * converting [ρ, θ] inputs into a [real, imag]-based complex number */ 53 static Complex fromPolar(Number rho, Number theta) { 54 [rho * Math.cos(theta), rho * Math.sin(theta)] as Complex 55 } 56 57 /** Creates new complex with same magnitude π;, but different angle θ; */ 58 Complex withTheta(Number theta) { fromPolar(this.rho, theta) } 59 60 /** Creates new complex with same angle θ;, but different magnitude ρ; */ 61 Complex withRho(Number rho) { fromPolar(rho, this.theta) } 62 63 static Complex exp(Complex c) { fromPolar(Math.exp(c.real), c.imag) } 64 65 static Complex log(Complex c) { [Math.log(c.rho), c.theta] as Complex } 66 67 Complex power(Complex c) { 68 this == 0 && c != 0 \ 69 ? [0] as Complex \ 70 : c == 1 \ 71 ? this \ 72 : exp( log(this) * c ) 73 } 74 75 Complex power(Number n) { this ** ([n, 0] as Complex) } 76 77 boolean equals(other) { 78 other != null && (other instanceof Complex \ 79 ? [real, imag] == [other.real, other.imag] \ 80 : other instanceof Number && [real, imag] == [other, 0]) 81 } 82 83 int hashCode() { [real, imag].hashCode() } 84 85 String toString() { 86 def realPart = "${real}" 87 def imagPart = imag.abs() == 1 ? "i" : "${imag.abs()}i" 88 real == 0 && imag == 0 \ 89 ? "0" \ 90 : real == 0 \ 91 ? (imag > 0 ? '' : "-") + imagPart \ 92 : imag == 0 \ 93 ? realPart \ 94 : realPart + (imag > 0 ? " + " : " - ") + imagPart 95 } 96 }
1 class Complex { 2 final Number real, imag 3
Ejemplo:
groovy:000> import Complex ===> [import Complex] groovy:000> a = new Complex(7,9) ===> 7 + 9i groovy:000> a.real = 4 ERROR groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: real for class: Complex at Complex.setProperty (Complex.groovy) at groovysh_evaluate.run (groovysh_evaluate:3) ...
4 static final Complex I = [0,1] as Complex
Complex(Number real) { this(real, 0) }
this
keyword
to call another constructor in the same class. Doing so is called an
explicit constructor invocation.
as
:
static final Complex I = [0,1] as Complexen este caso se llamará al constructor de
Complex
con argumentos los elementos
de la lista: [0, 1]
.
groovy:000> b = new Complex(-2,-1) ===> -2 - i groovy:000> a = b ===> -2 - i groovy:000> a = [7,3] as Complex ===> 7 + 3i groovy:000> a = [8,5] ===> [8, 5] groovy:000> a = (Complex) [8,5] ===> 8 + 5i
hashCode
de la clase Object.
83 int hashCode() { [real, imag].hashCode() }
Esto forma parte del contrato
que Java impone en la función hashCode
cuando se sobrecarga equals
:
public int hashCode()
Returns a hash code2.5 value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.
The general contract of hashCode
is:
hashCode
method must consistently
return the same integer, provided no information used in equals
comparisons on the object is modified. This integer need not remain
consistent from one execution of an application to another execution of
the same application.
equals
(Object)
method, then calling the hashCode
method on each of the two objects must
produce the same integer result.
equals
(Object) method, then calling the hashCode
method
on each of the two objects must produce distinct integer results. However,
the programmer should be aware that producing distinct integer results
for unequal objects may improve the performance of hashtables.
hashCode
method defined by
class Object does return distinct integers for distinct objects. (This
is typically implemented by converting the internal address of the
object into an integer, but this implementation technique is not
required by the Java programming language.)
toString
:
85 String toString() { 86 def realPart = "${real}" 87 def imagPart = imag.abs() == 1 ? "i" : "${imag.abs()}i" 88 real == 0 && imag == 0 \ 89 ? "0" \ 90 : real == 0 \ 91 ? (imag > 0 ? '' : "-") + imagPart \ 92 : imag == 0 \ 93 ? realPart \ 94 : realPart + (imag > 0 ? " + " : " - ") + imagPart 95 } 96 }
When Java converts data into its string representation during concatenation, it does so by calling one of the overloaded versions of the string conversion methodvalueOf()
defined byString
.
valueOf()
is
overloaded for all the simple types and for type Object.
valueOf()
returns a string that contains the human-readable
equivalent of the value with which it is called.
valueOf()
calls the toString()
method on the object.
The toString()
method is the means by which you can determine the string
representation for objects of classes that you create.
Every class implementstoString()
because it is defined by Object. However, the default implementation oftoString()
is seldom sufficient. For most important classes that you create, you will want to overridetoString()
and provide your own string representations.
By overridingtoString()
for classes that you create, you allow the resulting strings to be fully integrated into Java's programming environment. For example, they can be used inprint()
andprintln()
statements and in concatenation expressions.
generaciondecodigos@nereida:~/src/groovy/overloading$ cat -n useComplex.groovy 1 #!/usr/bin/env groovy 2 3 def tol = 0.000000001 // tolerance: acceptable "wrongness" to account for rounding error 4 5 println 'Demo 1: functionality as requested' 6 def a = [5,3] as Complex 7 println 'a == ' + a 8 def b = [0.5,6] as Complex 9 println 'b == ' + b 10 11 println "a + b == (${a}) + (${b}) == " + (a + b) 12 println "a * b == (${a}) * (${b}) == " + (a * b) 13 assert a + (-a) == 0 14 println "-a == -(${a}) == " + (-a) 15 assert (a * a.recip() - 1).abs() < tol 16 println "1/a == (${a}).recip() == " + (a.recip()) 17 println() 18 19 println 'Demo 2: other functionality not requested, but important for completeness' 20 println "a - b == (${a}) - (${b}) == " + (a - b) 21 println "a / b == (${a}) / (${b}) == " + (a / b) 22 println "a ** b == (${a}) ** (${b}) == " + (a ** b) 23 println 'a.real == ' + a.real 24 println 'a.imag == ' + a.imag 25 println 'a.rho == ' + a.rho 26 println 'a.theta == ' + a.theta 27 println 'a*~a == ' + a*~a 28 println 'sqrt(a*~a) == ' + (a*~a).power(0.5) 29 println '|a| == ' + a.abs() 30 println 'a_bar == ' + ~a 31 32 def rho = 10 33 def piOverTheta = 3 34 def theta = Math.PI / piOverTheta 35 def fromPolar1 = Complex.fromPolar(rho, theta) // direct polar-to-cartesian conversion 36 def fromPolar2 = Complex.exp(Complex.I * theta) * rho // Euler's equation 37 println "rho*cos(theta) + rho*i*sin(theta) == ${rho}*cos(pi/${piOverTheta}) + ${rho}*i*sin(pi/${piOverTheta}) == " + fromPolar1 38 println "rho * exp(i * theta) == ${rho} * exp(i * pi/${piOverTheta}) == " + fromPolar2 39 assert (fromPolar1 - fromPolar2).abs() < tol 40 println()
generaciondecodigos@nereida:~/src/groovy/overloading$ ./useComplex.groovy | cat -n 1 Demo 1: functionality as requested 2 a == 5 + 3i 3 b == 0.5 + 6i 4 a + b == (5 + 3i) + (0.5 + 6i) == 5.5 + 9i 5 a * b == (5 + 3i) * (0.5 + 6i) == -15.5 + 31.5i 6 -a == -(5 + 3i) == -5 - 3i 7 1/a == (5 + 3i).recip() == 0.1470588235 - 0.0882352941i 8 9 Demo 2: other functionality not requested, but important for completeness 10 a - b == (5 + 3i) - (0.5 + 6i) == 4.5 - 3i 11 a / b == (5 + 3i) / (0.5 + 6i) == 0.56551724145 - 0.78620689665i 12 a ** b == (5 + 3i) ** (0.5 + 6i) == -0.013750112198456855 - 0.09332524760169053i 13 a.real == 5 14 a.imag == 3 15 a.rho == 5.830951894845301 16 a.theta == 0.5404195002705842 17 a*~a == 34 18 sqrt(a*~a) == 5.830951894845301 19 |a| == 5.830951894845301 20 a_bar == 5 - 3i 21 rho*cos(theta) + rho*i*sin(theta) == 10*cos(pi/3) + 10*i*sin(pi/3) == 5.000000000000001 + 8.660254037844386i 22 rho * exp(i * theta) == 10 * exp(i * pi/3) == 5.000000000000001 + 8.660254037844386i