C sharp NET/Capítulo 7
Sobrecarga de operadores
[editar]
¿Qué es la sobrecarga de operadores?
[editar]La sobrecarga de operadores es la capacidad para transformar los operadores de un lenguaje como por ejemplo el +, -, etc, cuando se dice transformar se refiere a que los operandos que entran en juego no tienen que ser los que admite el lenguaje por defecto. Mediante esta técnica podemos sumar dos objetos creados por nosotros o un objeto y un entero, en vez de limitarnos a sumar números enteros o reales, por ejemplo.
La sobrecarga de operadores ya era posible en c++ y en otros lenguajes, pero sorprendentemente java no lo incorpora, así que podemos decir que esta característica es una ventaja de c# respecto a java, aunque mucha gente, esta posibilidad, no lo considera una ventaja porque complica el código.
A la hora de hablar de operadores vamos a distinguir entre dos tipos, los unarios y los binarios. Los unarios son aquellos que solo requieren un operando, por ejemplo a++, en este caso el operando es 'a' y el operador '++'. Los operadores binarios son aquellos que necesitan dos operadores, por ejemplo a+c , ahora el operador es '+' y los operandos 'a' y 'c'. Es importante esta distinción ya que la programación se hará de forma diferente.
Los operadores que podemos sobrecargar son los unarios, +, -, !, ~, ++, --; y los binarios +, -, *, /, %, &, |, ^, <<, >>. Es importante decir que los operadores de comparación, ==, !=, <, >, <=, >=, se pueden sobrecargar pero con la condición que siempre se sobrecargue el complementario, es decir, si sobrecargamos el == debemos sobrecargar el !=.
Sobrecargando operadores en la práctica
[editar]Para mostrar la sobrecarga vamos a usar el repetido ejemplo de los números complejos, ( aunque también valdría el de las coordenadas cartesianas ). Como se sabe, los números complejos tienen dos partes, la real y la imaginaria, cuando se suma dos números complejos su resultado es la suma de las dos partes, para ello se va a crear una clase llamada ComplexNum que contendrá ambas partes. Sin esta técnica no se podría sumar dos objetos de este tipo con este práctico método, ya que esta clase no es válida como operando de los operadores de c#.
Empecemos con el código de la clase de números complejos.
public class ComplexNum { private float img; private float real; // constructor de la clase public ComplexNum(float real, float img) { this.real = real; this.img = img; } // propiedad Real public float Real{ get{ return real; } set{ real = value; } } // propiedad Img public float Img{ get{ return img; } set{ img = value; } } // Sobrescribimos el miembro ToString heredado de Object override public string ToString() { if ( img >= 0 ) return real + "+" + img +"i"; else return real + "" + img + "i"; } public static ComplexNum operator+(ComplexNum a, ComplexNum b) { return new ComplexNum(a.real + b.real, a.img + b.img); } }
En el ejemplo hemos puesto la clase, con un constructor , dos propiedades para obtener los datos privados de la clase y un método que nos transfoma el número complejo a una cadena de caracteres para que se pueda visualizar fácilmente. Finalmente hemos sobrecargado el operador '+', de forma que podremos sumar dos números complejos como si se tratara de números usuales.
Operadores binarios
[editar]Para empezar vamos a sobrecargar el operador suma('+') para que al sumar dos objetos de la clase ComplexNum, es decir dos números complejos obtengamos un número complejo que será la suma de ambas partes. Cabe destacar que los prototipos para sobrecargar operadores serán:
public static Operando operator+(Operando a, Operando b)
Este es el prototipo para el operador +, el resto de operadores binarios van a seguir el mismo patrón. Por tanto el código del método de sobrecarga será el siguiente:
public static ComplexNum operator+(ComplexNum a, ComplexNum b) { return new ComplexNum(a.Real + b.Real, a.Img + b.Img); }
Este método sobrecarga el operador suma para que podamos sumar dos números complejos. Un dato a tener en cuenta es que los métodos que sobrecargan operadores deben ser static. Como se ve en el código los operandos son 'a' y 'b', que se reciben como parámetro y el resultado de la operación es otro número complejo que es el que retorna el método. Por tanto se limita a crear un nuevo número complejo con ambas partes operadas. De la misma forma podemos crear la sobrecarga del operador resta('-') para que lleve a cabo la misma función:
public static ComplexNum operator-(ComplexNum a, ComplexNum b) { return new ComplexNum(a.Real - b.Real, a.Img - b.Img); }
Como vemos el método es idéntico solo que sustituyendo los + por -. En este caso el trabajo que hacemos dentro del método es trivial pero podría ser tan complejo como se quisiera.
Operadores Unarios
[editar]En esta sección se verá cómo sobrecargar los operadores unarios, es decir aquellos que toman un solo operando, como por ejemplo a++. El prototipo de los métodos que van a sobrecargar operadores unarios será:
public static Operando operator++(Operando a)
Como antes sustituyendo el ++ por cualquier operador unario. El ejemplo dentro de nuestra clase de números complejos sería:
public static ComplexNum operator++(ComplexNum a) { float auximg = a.Img; float auxreal = a.Real; return new ComplexNum(++auxreal, ++auximg); }
A primera vista puede quedar la duda si estamos sobrecargando la operación ++a o a++. Este aspecto se encarga el compilador de resolverlo, es decir, se sobrecarga la operación ++ y el compilador se encarga de "sumar y asignar" o "asignar y sumar". Este problema no ocurría en C++, cosa que teníamos que manejar nosotros.
Como hemos dicho antes, la operación que hagamos dentro del método que sobrecarga el operador es totalmente libre, se puede poner el ejemplo de multiplicar dos matrices lo que es mas complejo que sumar dos números complejos.