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 definir como operadores como +, - ou == se comportam com suas classes personalizadas. Em vez de chamar métodos como point1.Add(point2), você pode escrever a forma 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 = 6O método deve ser public static, e pelo menos um parâmetro deve ser do 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 ==, também deverá definir !=.
Use sobrecarga de operadores quando isso tornar seu código mais intuitivo, especialmente para tipos matemáticos como vetores, números complexos ou dinheiro. Evite-a quando o significado da operação não for imediatamente óbvio.
Desafio
FácilVamos criar 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 classeFractionno namespaceMathque represente uma fração com um numerador e um denominador. Sua fração deve ter:- Duas propriedades inteiras somente leitura:
NumeratoreDenominator - Um construtor que aceite o numerador e o denominador (nessa ordem)
- Um operador
+sobrecarregado que some duas frações usando a fórmula:(a/b) + (c/d) = (a*d + c*b) / (b*d) - Um operador
*sobrecarregado que multiplique duas frações:(a/b) * (c/d) = (a*c) / (b*d) - Um operador
==sobrecarregado que retornetruese duas frações forem iguais (faça a multiplicação cruzada para comparar:a*d == c*b) - Um operador
!=sobrecarregado (obrigatório quando você sobrecarrega==) que retorne o oposto de== - Um método
GetDisplay()que retorne a fração como uma string no formato"{Numerator}/{Denominator}"
- Duas propriedades inteiras somente leitura:
Program.cs: No arquivo principal, crie duas frações usando valores de entrada. Demonstre os operadores sobrecarregados somando-as, multiplicando-as 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 deverá ser:
Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: TrueObserve como 1/2 e 2/4 são reconhecidas como iguais porque 1*4 == 2*2. A soma e o produto são calculados sem simplificação — isso não é um problema para este desafio. A beleza está em como agora você pode trabalhar naturalmente com frações usando operadores familiares!
Experimente você mesmo
using System;
using Math;
class Program
{
public static void Main(string[] args)
{
// Ler entrada para a primeira fração
int num1 = Convert.ToInt32(Console.ReadLine());
int den1 = Convert.ToInt32(Console.ReadLine());
// Ler entrada para a segunda fração
int num2 = Convert.ToInt32(Console.ReadLine());
int den2 = Convert.ToInt32(Console.ReadLine());
// TODO: Crie dois objetos Fraction usando os valores de entrada
// TODO: Use o operador + sobrecarregado para somar as frações
// TODO: Use o operador * sobrecarregado para multiplicar as frações
// TODO: Use o operador == sobrecarregado para verificar a igualdade
// TODO: Imprima a saída no formato exigido:
// Fração 1: {GetDisplay()}
// Fração 2: {GetDisplay()}
// Soma: {GetDisplay()}
// Produto: {GetDisplay()}
// Are equal: {True/False}
}
}
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
1Fundamentos de POO
Arquivos ExternosNamespaces e DiretivasIntrodução a Classes e ObjetosA Palavra-chave 'this'Métodos e ParâmetrosCampos vs PropriedadesConstrutoresInicializadores de ObjetosRecapitulação - Calculadora Simples4Herança
Sintaxe Básica de Herança (:)A Palavra-chave 'base'Palavras-chave Virtual e OverrideClasses SeladasA Classe Base 'object'Recapitulação - Hierarquia de Funcionários7Recursos Avançados
Sobrecarga de OperadoresIndexadores (this[])Sobrescrita de ToString()Métodos de ExtensãoRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoSingleton Thread-SafePadrão FactoryPadrão Observer (Eventos)Padrão Strategy2Propriedades e Membros Estáticos
Propriedades AutoimplementadasPropriedades de Apenas Leitura/EscritaCampos e Métodos EstáticosClasses EstáticasMembros com Corpo de Expressão5Polimorfismo e Interfaces
Polimorfismo: Compilação vs ExecuçãoInterface vs Classe AbstrataMúltiplas InterfacesInterfaces ExplícitasUpcasting e DowncastingRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição sobre HerançaGenerics (Classes e Métodos)Delegates e EventosAtributos e ReflectionIDisposable e a Instrução usingFundamentos de Injeção de Dependência11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Arquitetura de Classes
Dados de Instância vs EstáticosPalavras-chave 'readonly' e 'const'Campos de SuporteRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Modificadores de AcessoPropriedades para EncapsulamentoImplementação de Ocultação de DadosPadrões de ImutabilidadeRecapitulação - Registros de Estudantes9Argumentos Variáveis
A Palavra-chave 'params'Parâmetros OpcionaisArgumentos NomeadosSobrecarga de MétodosPratique por conta própria: Compilador de C# online