Sobrecarga de operadores
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy. Lección 36 de 70.
La sobrecarga de operadores te permite definir cómo se comportan operadores como +, - o == con tus clases personalizadas. En lugar de llamar a métodos como point1.Add(point2), puedes escribir la forma más natural point1 + point2.
Para realizar la sobrecarga de un operador, creas un método estático especial utilizando la palabra clave operator:
public class Vector
{
public int X { get; }
public int Y { get; }
public Vector(int x, int y)
{
X = x;
Y = y;
}
public static Vector operator +(Vector a, Vector b)
{
return new Vector(a.X + b.X, a.Y + b.Y);
}
}Ahora puedes sumar vectores de forma natural:
Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2; // X = 4, Y = 6El método debe ser public static, y al menos un parámetro debe ser el tipo contenedor. Puedes sobrecargar operadores aritméticos (+, -, *, /), operadores de comparación (==, !=, <, >) y operadores unarios (-, !, ++).
Ten en cuenta que los operadores de comparación deben sobrecargarse en pares: si defines ==, también debes definir !=.
Usa la sobrecarga de operadores cuando haga que tu código sea más intuitivo, especialmente para tipos matemáticos como vectores, números complejos o dinero. Evítala cuando el significado de la operación no sea inmediatamente evidente.
Desafío
FácilConstruyamos una clase Fraction que haga que trabajar con fracciones resulte natural mediante la sobrecarga de operadores. En lugar de llamar a métodos como fraction1.Add(fraction2), podrás escribir el intuitivo fraction1 + fraction2.
Organizarás tu código en dos archivos:
Fraction.cs: Crea una claseFractionen el espacio de nombresMathque represente una fracción con un numerador y un denominador. Tu fracción debe tener:- Dos propiedades enteras de solo lectura:
NumeratoryDenominator - Un constructor que acepte el numerador y el denominador (en ese orden)
- Un operador
+sobrecargado que sume dos fracciones usando la fórmula:(a/b) + (c/d) = (a*d + c*b) / (b*d) - Un operador
*sobrecargado que multiplique dos fracciones:(a/b) * (c/d) = (a*c) / (b*d) - Un operador
==sobrecargado que devuelvatruesi dos fracciones son iguales (multiplica en cruz para compararlas:a*d == c*b) - Un operador
!=sobrecargado (necesario cuando sobrecargas==) que devuelva lo contrario de== - Un método
GetDisplay()que devuelva la fracción como una cadena con el formato"{Numerator}/{Denominator}"
- Dos propiedades enteras de solo lectura:
Program.cs: En tu archivo principal, crea dos fracciones usando valores de entrada. Demuestra los operadores sobrecargados sumándolas, multiplicándolas y comprobando si son iguales. Imprime los resultados para mostrar que tus operadores funcionan de forma natural.
Recibirás cuatro entradas:
- Numerador de la primera fracción (entero)
- Denominador de la primera fracción (entero)
- Numerador de la segunda fracción (entero)
- Denominador de la segunda fracción (entero)
Imprime la salida con este formato:
Fraction 1: {GetDisplay()}
Fraction 2: {GetDisplay()}
Sum: {GetDisplay()}
Product: {GetDisplay()}
Are equal: {True/False}Por ejemplo, si las entradas son 1, 2, 2 y 4, la salida debería ser:
Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: TrueObserva cómo 1/2 y 2/4 se reconocen como iguales porque 1*4 == 2*2. La suma y el producto se calculan sin simplificación; eso está bien para este desafío. ¡La belleza está en lo natural que resulta trabajar ahora con fracciones usando operadores familiares!
Pruébalo tú mismo
using System;
using Math;
class Program
{
public static void Main(string[] args)
{
// Lee la entrada para la primera fracción
int num1 = Convert.ToInt32(Console.ReadLine());
int den1 = Convert.ToInt32(Console.ReadLine());
// Lee la entrada para la segunda fracción
int num2 = Convert.ToInt32(Console.ReadLine());
int den2 = Convert.ToInt32(Console.ReadLine());
// TODO: Crea dos objetos Fraction usando los valores de entrada
// TODO: Usa el operador + sobrecargado para sumar las fracciones
// TODO: Usa el operador * sobrecargado para multiplicar las fracciones
// TODO: Usa el operador == sobrecargado para comprobar la igualdad
// TODO: Imprime la salida en el formato requerido:
// Fracción 1: {GetDisplay()}
// Fracción 2: {GetDisplay()}
// Suma: {GetDisplay()}
// Producto: {GetDisplay()}
// Are equal: {True/False}
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosNamespaces y directivasIntro a clases y objetosLa palabra clave 'this'Métodos y parámetrosCampos vs PropiedadesConstructoresInicializadores de objetosResumen - Calculadora simple4Herencia
Sintaxis básica de herencia (:)La palabra clave 'base'Palabras clave Virtual y OverrideClases selladas (Sealed)La clase base 'object'Resumen: Jerarquía de empleados7Características avanzadas
Sobrecarga de operadoresIndexadores (this[])Sobrescritura de ToString()Métodos de extensiónResumen - Lista personalizada10Patrones de diseño - Parte 1
Introducción a los patrones de diseñoSingleton Thread-SafePatrón FactoryPatrón Observer (Eventos)Patrón Strategy2Propiedades y miembros estáticos
Propiedades autoimplementadasPropiedades de solo lectura y escrituraCampos y métodos estáticosClases estáticasMiembros con cuerpo de expresión5Polimorfismo e Interfaces
Polimorfismo: Compilación vs. EjecuciónInterfaz vs. Clase AbstractaInterfaces MúltiplesInterfaces ExplícitasUpcasting y DowncastingRepaso: Calculadora de Figuras8Conceptos avanzados de POO
Composición sobre herenciaGenéricos (clases y métodos)Delegados y eventosAtributos y ReflexiónIDisposable y la sentencia usingFundamentos de Inyección de dependencias11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Arquitectura de clases
Datos de instancia vs. estáticosPalabras clave 'readonly' y 'const'Campos de respaldoResumen - Gestor de cuentas bancarias6Encapsulamiento
Modificadores de accesoPropiedades para el encapsulamientoImplementación de ocultamiento de datosPatrones de inmutabilidadRepaso - Registros de estudiantesPractica por tu cuenta: Compilador de C# online