Menu
Coddy logo textTech

Przeciążanie operatorów

Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 36 z 70.

Przeciążanie operatorów pozwala określić, jak operatory takie jak +, - czy == działają z Twoimi własnymi klasami. Zamiast wywoływać metody, takie jak point1.Add(point2), możesz zapisać to w bardziej naturalny sposób: point1 + point2.

Aby przeciążyć operator, utwórz specjalną metodę statyczną, używając słowa kluczowego 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);
    }
}

Teraz możesz w naturalny sposób dodawać wektory:

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

Metoda musi być public static, a co najmniej jeden parametr musi być typu zawierającego tę metodę. Możesz przeciążać operatory arytmetyczne (+, -, *, /), operatory porównania (==, !=, <, >) oraz operatory jednoargumentowe (-, !, ++).

Pamiętaj, że operatory porównania muszą być przeciążane parami — jeśli zdefiniujesz ==, musisz również zdefiniować !=.

Używaj przeciążania operatorów, gdy sprawia, że Twój kod jest bardziej intuicyjny, szczególnie w przypadku typów matematycznych, takich jak wektory, liczby zespolone czy pieniądze. Unikaj go, gdy znaczenie operacji nie jest od razu oczywiste.

challenge icon

Wyzwanie

Łatwy

Stwórzmy klasę Fraction, dzięki której praca z ułamkami będzie naturalna za sprawą przeciążania operatorów. Zamiast wywoływać metody, takie jak fraction1.Add(fraction2), będzie można zapisać intuicyjne fraction1 + fraction2.

Podzielisz kod na dwa pliki:

  • Fraction.cs: Utwórz klasę Fraction w przestrzeni nazw Math, która reprezentuje ułamek z licznikiem i mianownikiem. Ułamek powinien mieć:
    • Dwie tylko do odczytu właściwości typu całkowitego: Numerator i Denominator
    • Konstruktor, który przyjmuje licznik i mianownik (w tej kolejności)
    • Przeciążony operator +, który dodaje dwa ułamki według wzoru: (a/b) + (c/d) = (a*d + c*b) / (b*d)
    • Przeciążony operator *, który mnoży dwa ułamki: (a/b) * (c/d) = (a*c) / (b*d)
    • Przeciążony operator ==, który zwraca true, jeśli dwa ułamki są równe (porównaj je przez mnożenie krzyżowe: a*d == c*b)
    • Przeciążony operator != (wymagany przy przeciążaniu ==), który zwraca wartość przeciwną do ==
    • Metodę GetDisplay(), która zwraca ułamek jako ciąg znaków w formacie "{Numerator}/{Denominator}"
  • Program.cs: W pliku głównym utwórz dwa ułamki na podstawie wartości wejściowych. Zademonstruj działanie przeciążonych operatorów, dodając i mnożąc ułamki oraz sprawdzając, czy są równe. Wypisz wyniki, aby pokazać, jak naturalnie działają te operatory.

Otrzymasz cztery dane wejściowe:

  • Licznik pierwszego ułamka (liczba całkowita)
  • Mianownik pierwszego ułamka (liczba całkowita)
  • Licznik drugiego ułamka (liczba całkowita)
  • Mianownik drugiego ułamka (liczba całkowita)

Wypisz wynik w tym formacie:

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

Na przykład jeśli dane wejściowe to 1, 2, 2 i 4, wynik powinien wyglądać następująco:

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

Zwróć uwagę, że 1/2 i 2/4 są uznawane za równe, ponieważ 1*4 == 2*2. Suma i iloczyn są obliczane bez skracania — w tym wyzwaniu to w porządku. Najważniejsze jest to, że teraz możesz tak naturalnie wykonywać działania na ułamkach za pomocą znanych operatorów!

Spróbuj swoich sił

using System;
using Math;

class Program
{
    public static void Main(string[] args)
    {
        // Wczytaj dane wejściowe dla pierwszego ułamka
        int num1 = Convert.ToInt32(Console.ReadLine());
        int den1 = Convert.ToInt32(Console.ReadLine());
        
        // Wczytaj dane wejściowe dla drugiego ułamka
        int num2 = Convert.ToInt32(Console.ReadLine());
        int den2 = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Utwórz dwa obiekty Fraction, używając wczytanych wartości
        
        // TODO: Użyj przeciążonego operatora +, aby dodać ułamki
        
        // TODO: Użyj przeciążonego operatora *, aby pomnożyć ułamki
        
        // TODO: Użyj przeciążonego operatora ==, aby sprawdzić równość
        
        // TODO: Wyświetl wynik w wymaganym formacie:
        // Ułamek 1: {GetDisplay()}
        // Ułamek 2: {GetDisplay()}
        // Suma: {GetDisplay()}
        // Iloczyn: {GetDisplay()}
        // Czy są równe: {True/False}
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C# online