Operatorüberladung
Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy — Lektion 36 von 70.
Operatorüberladung ermöglicht es Ihnen zu definieren, wie Operatoren wie +, - oder == sich bei Ihren benutzerdefinierten Klassen verhalten. Anstatt Methoden wie point1.Add(point2) aufzurufen, können Sie das natürlichere point1 + point2 schreiben.
Um einen Operator zu überladen, erstellen Sie eine spezielle statische Methode unter Verwendung des Schlüsselworts 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);
}
}Jetzt können Sie Vektoren auf natürliche Weise addieren:
Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2; // X = 4, Y = 6Die Methode muss public static sein, und mindestens ein Parameter muss der enthaltende Typ sein. Sie können arithmetische Operatoren (+, -, *, /), Vergleichsoperatoren (==, !=, <, >) und unäre Operatoren (-, !, ++) überladen.
Beachten Sie, dass Vergleichsoperatoren paarweise überladen werden müssen – wenn Sie == definieren, müssen Sie auch != definieren.
Verwenden Sie Operatorüberladung, wenn sie Ihren Code intuitiver macht, insbesondere für mathematische Typen wie Vektoren, komplexe Zahlen oder Geld. Vermeiden Sie sie, wenn die Bedeutung der Operation nicht sofort ersichtlich ist.
Aufgabe
EinfachLassen Sie uns eine Fraction-Klasse erstellen, die die Arbeit mit Brüchen durch Operatorüberladung natürlich erscheinen lässt. Anstatt Methoden wie fraction1.Add(fraction2) aufzurufen, werden Sie in der Lage sein, das intuitive fraction1 + fraction2 zu schreiben.
Sie werden Ihren Code auf zwei Dateien verteilen:
Fraction.cs: Erstellen Sie eineFraction-Klasse im NamespaceMath, die einen Bruch mit einem Zähler und einem Nenner darstellt. Ihr Bruch sollte Folgendes haben:- Zwei schreibgeschützte Integer-Eigenschaften:
NumeratorundDenominator - Einen Konstruktor, der den Zähler und den Nenner (in dieser Reihenfolge) akzeptiert
- Einen überladenen
+-Operator, der zwei Brüche nach der Formel addiert:(a/b) + (c/d) = (a*d + c*b) / (b*d) - Einen überladenen
*-Operator, der zwei Brüche multipliziert:(a/b) * (c/d) = (a*c) / (b*d) - Einen überladenen
==-Operator, dertruezurückgibt, wenn zwei Brüche gleich sind (verwenden Sie die Überkreuzmultiplikation zum Vergleich:a*d == c*b) - Einen überladenen
!=-Operator (erforderlich, wenn Sie==überladen), der das Gegenteil von==zurückgibt - Eine Methode
GetDisplay(), die den Bruch als String im Format"{Numerator}/{Denominator}"zurückgibt
- Zwei schreibgeschützte Integer-Eigenschaften:
Program.cs: Erstellen Sie in Ihrer Hauptdatei zwei Brüche unter Verwendung von Eingabewerten. Demonstrieren Sie die überladenen Operatoren, indem Sie sie addieren, multiplizieren und prüfen, ob sie gleich sind. Geben Sie die Ergebnisse aus, um zu zeigen, dass Ihre Operatoren natürlich funktionieren.
Sie erhalten vier Eingaben:
- Zähler des ersten Bruchs (Integer)
- Nenner des ersten Bruchs (Integer)
- Zähler des zweiten Bruchs (Integer)
- Nenner des zweiten Bruchs (Integer)
Geben Sie die Ausgabe in diesem Format aus:
Fraction 1: {GetDisplay()}
Fraction 2: {GetDisplay()}
Sum: {GetDisplay()}
Product: {GetDisplay()}
Are equal: {True/False}Wenn die Eingaben beispielsweise 1, 2, 2 und 4 sind, sollte die Ausgabe wie folgt aussehen:
Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: TrueBeachten Sie, wie 1/2 und 2/4 als gleich erkannt werden, da 1*4 == 2*2 gilt. Die Summe und das Produkt werden ohne Kürzen berechnet – das ist für diese Herausforderung in Ordnung. Das Schöne daran ist, wie natürlich Sie jetzt mit Brüchen unter Verwendung vertrauter Operatoren arbeiten können!
Spickzettel
Operatorüberladung ermöglicht es Ihnen, benutzerdefiniertes Verhalten für Operatoren wie +, -, *, == mit Ihren Klassen zu definieren.
Um einen Operator zu überladen, erstellen Sie eine public static Methode unter Verwendung des Schlüsselworts operator. Mindestens ein Parameter muss vom enthaltenden Typ sein:
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);
}
}Verwendung:
Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2; // X = 4, Y = 6Sie können Folgendes überladen:
- Arithmetische Operatoren:
+,-,*,/ - Vergleichsoperatoren:
==,!=,<,>(müssen paarweise überladen werden) - Unäre Operatoren:
-,!,++
Wenn Sie == überladen, müssen Sie auch != überladen:
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);
}Probier es selbst
using System;
using Math;
class Program
{
public static void Main(string[] args)
{
// Eingabe für den ersten Bruch lesen
int num1 = Convert.ToInt32(Console.ReadLine());
int den1 = Convert.ToInt32(Console.ReadLine());
// Eingabe für den zweiten Bruch lesen
int num2 = Convert.ToInt32(Console.ReadLine());
int den2 = Convert.ToInt32(Console.ReadLine());
// TODO: Erstelle zwei Fraction-Objekte mit den Eingabewerten
// TODO: Verwende den überladenen +-Operator, um die Brüche zu addieren
// TODO: Verwende den überladenen *-Operator, um die Brüche zu multiplizieren
// TODO: Verwende den überladenen ==-Operator, um auf Gleichheit zu prüfen
// TODO: Gib die Ausgabe im erforderlichen Format aus:
// Fraction 1: {GetDisplay()}
// Fraction 2: {GetDisplay()}
// Sum: {GetDisplay()}
// Product: {GetDisplay()}
// Are equal: {True/False}
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienNamespaces & DirektivenEinführung in Klassen & ObjekteDas 'this'-SchlüsselwortMethoden und ParameterFelder vs. EigenschaftenKonstruktorenObjekt-InitialisiererZusammenfassung - Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (:) SyntaxDas 'base'-SchlüsselwortVirtual & Override SchlüsselwörterVersiegelte KlassenDie 'object'-BasisklasseZusammenfassung – Mitarbeiter-Hierarchie7Fortgeschrittene Funktionen
OperatorüberladungIndexer (this[])ToString() überschreibenErweiterungsmethodenZusammenfassung - Benutzerdefinierte Liste2Eigenschaften & Statische Member
Automatisch implementierte EigenschaftenRead-Only- & Write-Only-EigenschaftenStatische Felder & MethodenStatische KlassenExpression-Bodied Member5Polymorphismus & Interfaces
Compile- vs. Runtime-PolymorphismusInterface vs. abstrakte KlasseMehrfache InterfacesExplizite InterfacesUpcasting & DowncastingRecap – Shape Calculator3Klassenarchitektur
Instanz- vs. statische Daten'readonly' & 'const' SchlüsselwörterBacking FieldsZusammenfassung - Bankkonto-Manager6Kapselung
ZugriffsmodifikatorenProperties zur KapselungImplementierung von Data HidingImmutability-MusterRückblick – Studierendendaten