Surcharge d'opérateurs
Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy — leçon 36 sur 70.
La surcharge d'opérateurs vous permet de définir comment les opérateurs comme +, - ou == se comportent avec vos classes personnalisées. Au lieu d'appeler des méthodes comme point1.Add(point2), vous pouvez écrire le plus naturel point1 + point2.
Pour surcharger un opérateur, vous créez une méthode statique spéciale en utilisant le mot-clé 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);
}
}Maintenant, vous pouvez ajouter des vecteurs naturellement :
Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2; // X = 4, Y = 6La méthode doit être public static, et au moins un paramètre doit être le type conteneur. Vous pouvez surcharger les opérateurs arithmétiques (+, -, *, /), les opérateurs de comparaison (==, !=, <, >) et les opérateurs unaires (-, !, ++).
Notez que les opérateurs de comparaison doivent être surchargés par paires - si vous définissez ==, vous devez également définir !=.
Utilisez la surcharge d'opérateurs lorsqu'elle rend votre code plus intuitif, particulièrement pour les types mathématiques comme les vecteurs, les nombres complexes ou la monnaie. Évitez-la lorsque la signification de l'opération n'est pas immédiatement évidente.
Défi
FacileConstruisons une classe Fraction qui rend le travail avec les fractions naturel grâce à la surcharge d'opérateurs. Au lieu d'appeler des méthodes comme fraction1.Add(fraction2), vous pourrez écrire l'intuitif fraction1 + fraction2.
Vous organiserez votre code sur deux fichiers :
Fraction.cs: Créez une classeFractiondans l'espace de nomsMathqui représente une fraction avec un numérateur et un dénominateur. Votre fraction doit avoir :- Deux propriétés entières en lecture seule :
NumeratoretDenominator - Un constructeur qui accepte le numérateur et le dénominateur (dans cet ordre)
- Un opérateur
+surchargé qui additionne deux fractions en utilisant la formule :(a/b) + (c/d) = (a*d + c*b) / (b*d) - Un opérateur
*surchargé qui multiplie deux fractions :(a/b) * (c/d) = (a*c) / (b*d) - Un opérateur
==surchargé qui retournetruesi deux fractions sont égales (utilisez la multiplication croisée pour comparer :a*d == c*b) - Un opérateur
!=surchargé (requis lorsque vous surchargez==) qui retourne l'opposé de== - Une méthode
GetDisplay()qui retourne la fraction sous forme de chaîne de caractères au format"{Numerator}/{Denominator}"
- Deux propriétés entières en lecture seule :
Program.cs: Dans votre fichier principal, créez deux fractions en utilisant les valeurs d'entrée. Démontrez les opérateurs surchargés en les additionnant, en les multipliant et en vérifiant s'ils sont égaux. Affichez les résultats pour montrer vos opérateurs fonctionnant naturellement.
Vous recevrez quatre entrées :
- Le numérateur de la première fraction (entier)
- Le dénominateur de la première fraction (entier)
- Le numérateur de la deuxième fraction (entier)
- Le dénominateur de la deuxième fraction (entier)
Affichez la sortie dans ce format :
Fraction 1: {GetDisplay()}
Fraction 2: {GetDisplay()}
Sum: {GetDisplay()}
Product: {GetDisplay()}
Are equal: {True/False}Par exemple, si les entrées sont 1, 2, 2, et 4, la sortie devrait être :
Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: TrueRemarquez comment 1/2 et 2/4 sont reconnus comme égaux parce que 1*4 == 2*2. La somme et le produit sont calculés sans simplification - c'est correct pour ce défi. La beauté réside dans la façon naturelle dont vous pouvez maintenant travailler avec des fractions en utilisant des opérateurs familiers !
Aide-mémoire
La surcharge d'opérateurs vous permet de définir un comportement personnalisé pour des opérateurs tels que +, -, *, == avec vos classes.
Pour surcharger un opérateur, créez une méthode public static en utilisant le mot-clé operator. Au moins un paramètre doit être du type contenant :
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);
}
}Utilisation :
Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2; // X = 4, Y = 6Vous pouvez surcharger :
- Les opérateurs arithmétiques :
+,-,*,/ - Les opérateurs de comparaison :
==,!=, <code><,(doivent être surchargés par paires) - Les opérateurs unaires :
-,!,++
Lors de la surcharge de ==, vous devez également surcharger != :
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);
}Essayez vous-même
using System;
using Math;
class Program
{
public static void Main(string[] args)
{
// Lire l'entrée pour la première fraction
int num1 = Convert.ToInt32(Console.ReadLine());
int den1 = Convert.ToInt32(Console.ReadLine());
// Lire l'entrée pour la deuxième fraction
int num2 = Convert.ToInt32(Console.ReadLine());
int den2 = Convert.ToInt32(Console.ReadLine());
// TODO: Créer deux objets Fraction en utilisant les valeurs d'entrée
// TODO: Utiliser l'opérateur + surchargé pour additionner les fractions
// TODO: Utiliser l'opérateur * surchargé pour multiplier les fractions
// TODO: Utiliser l'opérateur == surchargé pour vérifier l'égalité
// TODO: Afficher la sortie au format requis :
// Fraction 1: {GetDisplay()}
// Fraction 2: {GetDisplay()}
// Sum: {GetDisplay()}
// Product: {GetDisplay()}
// Are equal: {True/False}
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesEspaces de noms et directivesIntro aux classes et objetsLe mot-clé 'this'Méthodes et paramètresChamps vs PropriétésConstructeursInitialiseurs d'objetsRécapitulatif - Calculatrice simple4Héritage
Syntaxe de base de l'héritage (:)Le mot-clé 'base'Mots-clés Virtual & OverrideClasses scelléesLa classe de base 'object'Récapitulatif - Hiérarchie des employés7Fonctionnalités avancées
Surcharge d'opérateursIndexeurs (this[])Redéfinition de ToString()Méthodes d'extensionRécapitulatif - Liste personnalisée10Patrons de conception - Partie 1
Introduction aux patrons de conceptionSingleton Thread-SafePatron FabriquePatron Observateur (Événements)Patron Stratégie2Propriétés et membres statiques
Propriétés auto-implémentéesPropriétés en lecture/écriture seuleChamps et méthodes statiquesClasses statiquesMembres à corps d'expression5Polymorphisme & Interfaces
Polymorphisme : Compilation vs ExécutionInterface vs Classe AbstraiteInterfaces MultiplesInterfaces ExplicitesUpcasting & DowncastingRécapitulatif - Calculateur de Formes8Concepts avancés de la POO
Composition plutôt qu'héritageGénériques (Classes et Méthodes)Délégués et ÉvénementsAttributs et RéflexionIDisposable et l'instruction usingBases de l'Injection de Dépendances11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Architecture des classes
Données d'instance vs statiquesMots-clés 'readonly' & 'const'Champs de supportRécapitulatif - Gestionnaire de compte bancaire6Encapsulation
Modificateurs d'accèsPropriétés pour l'encapsulationImplémentation du masquage de donnéesPatterns d'immuabilitéRécapitulatif - Dossiers d'étudiants12Projet : Système de gestion de bibliothèque
Structure du projetModèles Livre et Utilisateur