Aprendiendo .NET sobre la marcha: Operadores
<< APRENDIENDO .NET SOBRE LA MARCHA: VIEJOS WINDOWS FORMS (II)
Anres de continuar hacia el final de nuestra aplicación, y dato que son muchas cosas más las que debe incluir (pondré el proyecto completo para descargar con el link en la publicación siguiente), abordaré un tema que es útil, aunque de momento le veo aplicación directa en desarrollos de ciencias exactas. Para ello desarrollamos una clase que procedo a explicar.
Ahí les encargo pensar alguna aplicación para la sobrecarga de operadores. Ojalá puedan comentar sus ideas
La clase en cuestión tiene como objetivo que se realicen cálculos de rectas basándonos en los puntos que las definen, y como trabajamos con divisiones, pensemos que para reducir posibles errores de arrastre por redondeo de decimales, haremos explícitas las divisiones presentando los números como fracciones o quebrados.
public class Racional {
private int _numerador, _denominador;
private float _decimal;
public int Numerador {
get {
return _numerador;
}
set {
_numerador = value;
if (_denominador != 0)
_decimal = (float)_numerador / (float)_denominador;
}
}
public int Denominador {
get {
return _denominador;
}
set {
_denominador = value;
if (_denominador != 0)
_decimal = (float)_numerador / (float)_denominador;
}
}
public float Decimal {
get {
return _decimal;
}
set {
_decimal = value;
string[] s = _decimal.ToString().Split('.');
if (s.Length > 1) {
_numerador = int.Parse(s[0] + s[1]);
_denominador = (int)Math.Pow(10, s[1].Length);
}
}
}
public Racional() {
Numerador = 0;
Denominador = 1;
}
public Racional(int n, int d) {
Numerador = n;
Denominador = d;
}
public Racional(float d) {
Decimal = d;
}
public override string ToString() {
return string.Format("{0}/{1}", Numerador, Denominador);
}
//-- termina la clase y en vez del comentario se pondrá el código que sigue más adelante --//
}
Hasta aquí todo es normal: definimos una clase con tres variables privadas y tres propiedades, donde lo interesante es que si especificamos numerados y denominador, el resultado decimal se calcula, y si especificamos el decimal, entonces numerados y denominador se definen solitos. Además de que sobrecargamos el método ToString para que su expresión como cadena sea la fracción.
EL siguiente código sobreescribe los operadores para que funcionen con objetos de nuestra clase Racional. Con esto nos permitimos definir dos objetos como instancias de Racional con numerador y denominador, y las operaciones las hacemos sobre estos elementos, lo que nos regresa un número de punto flotante, su representación como texto en fracción y usar por separado el numerador y el denominador.
public static Racional operator +(Racional r1, Racional r2) {
return new Racional(
r1.Numerador * r2.Denominador + r2.Numerador * r1.Denominador,
r1.Denominador * r2.Denominador);
}
public static Racional operator -(Racional r1, Racional r2) {
return new Racional(
r1.Numerador * r2.Denominador - r2.Numerador * r1.Denominador,
r1.Denominador * r2.Denominador);
}
public static Racional operator *(Racional r1, Racional r2) {
return new Racional(r1.Numerador * r2.Numerador, r1.Denominador * r2.Denominador);
}
public static Racional operator /(Racional r1, Racional r2) {
return new Racional(r1.Numerador * r2.Denominador, r1.Denominador * r2.Numerador);
}
Es una clase muy básica, de hecho podemos ampliarla a más operaciones, como m.c.m., y M.C.D., además de simplificación, potencias y raíces. La aplicación de esta clase es para el proyecto completo, pero aquí pongo las clases Punto y Recta que se van a utilizar
public class Punto {
public Racional X { get; set; }
public Racional Y { get; set; }
public override string ToString() {
return string.Format("({0} , {1})", X.Decimal, Y.Decimal);
}
public override bool Equals(object p) {
if (p is Punto)
return (p as Punto).X.Equals(X) && (p as Punto).Y.Equals(Y);
else
return false;
}
public override int GetHashCode() {
return base.GetHashCode();
}
}
public class Recta {
public Punto P { get; set; }
public Punto Q { get; set; }
public Racional Pendiente { get; set; }
public void calcularPendiente() {
Pendiente = (Q.Y - P.Y) / (Q.X - P.X);
}
public string ecuacionPuntoPendiente() {
calcularPendiente();
var independiente = P.Y - (Pendiente * P.X);
return string.Format("{0}x - y + ({1}) = 0", Pendiente, independiente);
}
}
Como se puede ver, gracias a los operadores sobrecargados para la clase Racional, es muy sencillo implementar las operaciones de las clases Punto y Recta
Agradezco los comentarios que puedan hacerme, así como el que se suscriban para recibir noticias y, si consideran útil, compartir mi blog.
Comentarios
Publicar un comentario