Menu
Coddy logo textTech

Sobrecarga de Operadores

Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy — lição 36 de 70.

A sobrecarga de operadores permite que você defina como operadores como +, - ou == se comportam com suas classes personalizadas. Em vez de chamar métodos como point1.Add(point2), você pode escrever o mais natural point1 + point2.

Para sobrecarregar um operador, você cria um método estático especial usando a palavra-chave 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);
    }
}

Agora você pode adicionar vetores naturalmente:

Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2;  // X = 4, Y = 6

O método deve ser public static, e pelo menos um parâmetro deve ser o tipo que o contém. Você pode sobrecarregar operadores aritméticos (+, -, *, /), operadores de comparação (==, !=, <, >) e operadores unários (-, !, ++).

Observe que os operadores de comparação devem ser sobrecarregados em pares - se você definir ==, você também deve definir !=.

Use a sobrecarga de operadores quando ela tornar seu código mais intuitivo, particularmente para tipos matemáticos como vetores, números complexos ou dinheiro. Evite-a quando o significado da operação não for imediatamente óbvio.

challenge icon

Desafio

Fácil

Vamos construir uma classe Fraction que torne o trabalho com frações natural por meio da sobrecarga de operadores. Em vez de chamar métodos como fraction1.Add(fraction2), você poderá escrever o intuitivo fraction1 + fraction2.

Você organizará seu código em dois arquivos:

  • Fraction.cs: Crie uma classe Fraction no namespace Math que represente uma fração com um numerador e um denominador. Sua fração deve ter:
    • Duas propriedades inteiras somente leitura: Numerator e Denominator
    • Um construtor que aceita o numerador e o denominador (nessa ordem)
    • Um operador + sobrecarregado que soma duas frações usando a fórmula: (a/b) + (c/d) = (a*d + c*b) / (b*d)
    • Um operador * sobrecarregado que multiplica duas frações: (a/b) * (c/d) = (a*c) / (b*d)
    • Um operador == sobrecarregado que retorna true se duas frações forem iguais (use a multiplicação cruzada para comparar: a*d == c*b)
    • Um operador != sobrecarregado (obrigatório ao sobrecarregar ==) que retorna o oposto de ==
    • Um método GetDisplay() que retorna a fração como uma string no formato "{Numerator}/{Denominator}"
  • Program.cs: No seu arquivo principal, crie duas frações usando valores de entrada. Demonstre os operadores sobrecarregados somando-os, multiplicando-os e verificando se são iguais. Imprima os resultados para mostrar seus operadores funcionando naturalmente.

Você receberá quatro entradas:

  • Numerador da primeira fração (inteiro)
  • Denominador da primeira fração (inteiro)
  • Numerador da segunda fração (inteiro)
  • Denominador da segunda fração (inteiro)

Imprima a saída neste formato:

Fraction 1: {GetDisplay()}
Fraction 2: {GetDisplay()}
Sum: {GetDisplay()}
Product: {GetDisplay()}
Are equal: {True/False}

Por exemplo, se as entradas forem 1, 2, 2 e 4, a saída deve ser:

Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: True

Observe como 1/2 e 2/4 são reconhecidos como iguais porque 1*4 == 2*2. A soma e o produto são calculados sem simplificação - tudo bem para este desafio. A beleza está na naturalidade com que você agora pode trabalhar com frações usando operadores familiares!

Folha de consulta

A sobrecarga de operadores permite que você defina um comportamento personalizado para operadores como +, -, *, == com suas classes.

Para sobrecarregar um operador, crie um método public static usando a palavra-chave operator. Pelo menos um parâmetro deve ser do tipo que o contém:

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);
    }
}

Uso:

Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2;  // X = 4, Y = 6

Você pode sobrecarregar:

  • Operadores aritméticos: +, -, *, /
  • Operadores de comparação: ==, !=, <code><, (devem ser sobrecarregados em pares)
  • Operadores unários: -, !, ++

Ao sobrecarregar ==, você também deve sobrecarregar !=:

public static bool operator ==(Vector a, Vector b)
{
    return a.X == b.X && a.Y == b.Y;
}

public static bool operator !=(Vector a, Vector b)
{
    return !(a == b);
}

Experimente você mesmo

using System;
using Math;

class Program
{
    public static void Main(string[] args)
    {
        // Lê a entrada para a primeira fração
        int num1 = Convert.ToInt32(Console.ReadLine());
        int den1 = Convert.ToInt32(Console.ReadLine());
        
        // Lê a entrada para a segunda fração
        int num2 = Convert.ToInt32(Console.ReadLine());
        int den2 = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Criar dois objetos Fraction usando os valores de entrada
        
        // TODO: Usar o operador + sobrecarregado para somar as frações
        
        // TODO: Usar o operador * sobrecarregado para multiplicar as frações
        
        // TODO: Usar o operador == sobrecarregado para verificar a igualdade
        
        // TODO: Imprimir a saída no formato exigido:
        // Fraction 1: {GetDisplay()}
        // Fraction 2: {GetDisplay()}
        // Sum: {GetDisplay()}
        // Product: {GetDisplay()}
        // Are equal: {True/False}
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos