运算符重载
本课属于 Coddy C# 学习旅程的“面向对象编程”单元。第 36 课,共 70 课。
运算符重载可以让你定义 +、- 或 == 等运算符在自定义类中的行为。你可以直接写更自然的 point1 + point2,而不用调用 point1.Add(point2) 这样的方法。
要重载运算符,你需要使用 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);
}
}现在你可以自然地相加向量:
Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2; // X = 4, Y = 6该方法必须是 public static,并且至少有一个参数的类型是包含它的类型。你可以重载算术运算符(+、-、*、/)、比较运算符(==、!=、<、>)和一元运算符(-、!、++)。
请注意,比较运算符必须成对重载。如果定义了 ==,也必须定义 !=。
当运算符重载能让代码更直观时,就使用它,尤其是处理向量、复数或货币等数学类型时。如果某个运算的含义不够直观,就不要使用运算符重载。
挑战
简单我们来创建一个 Fraction 类,通过运算符重载,让分数的使用更加自然。你不必调用 fraction1.Add(fraction2) 这样的方法,而是可以直观地写出 fraction1 + fraction2。
你需要将代码分成两个文件:
Fraction.cs:在Math命名空间中创建一个Fraction类,用分子和分母表示一个分数。这个分数应包含:- 两个只读整数属性:
Numerator和Denominator - 一个按此顺序接收分子和分母的构造函数
- 一个重载的
+运算符,使用以下公式将两个分数相加:(a/b) + (c/d) = (a*d + c*b) / (b*d) - 一个重载的
*运算符,用于将两个分数相乘:(a/b) * (c/d) = (a*c) / (b*d) - 一个重载的
==运算符,如果两个分数相等则返回true(通过交叉相乘进行比较:a*d == c*b) - 一个重载的
!=运算符(重载==时必须重载),返回与==相反的结果 - 一个
GetDisplay()方法,以"{Numerator}/{Denominator}"格式将分数作为字符串返回
- 两个只读整数属性:
Program.cs:在主文件中,使用输入值创建两个分数。通过将它们相加、相乘并检查它们是否相等,演示重载运算符。打印结果,展示运算符如何自然地发挥作用。
你将收到 4 个输入:
- 第一个分数的分子(整数)
- 第一个分数的分母(整数)
- 第二个分数的分子(整数)
- 第二个分数的分母(整数)
按照以下格式打印输出:
Fraction 1: {GetDisplay()}
Fraction 2: {GetDisplay()}
Sum: {GetDisplay()}
Product: {GetDisplay()}
Are equal: {True/False}例如,如果输入是 1、2、2 和 4,输出应为:
Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: True注意,1/2 和 2/4 会被识别为相等,因为 1*4 == 2*2。求和和乘积的计算不会约分,这对这个挑战来说没问题。妙处在于,现在你可以用熟悉的运算符,自然地对分数进行运算!
亲手试试
using System;
using Math;
class Program
{
public static void Main(string[] args)
{
// 读取第一个分数的输入
int num1 = Convert.ToInt32(Console.ReadLine());
int den1 = Convert.ToInt32(Console.ReadLine());
// 读取第二个分数的输入
int num2 = Convert.ToInt32(Console.ReadLine());
int den2 = Convert.ToInt32(Console.ReadLine());
// TODO: 用输入的值创建两个 Fraction 对象
// TODO: 使用重载的 + 运算符将两个分数相加
// TODO: 使用重载的 * 运算符将两个分数相乘
// TODO: 使用重载的 == 运算符检查两个分数是否相等
// TODO: 按要求的格式输出:
// 分数 1:{GetDisplay()}
// 分数 2:{GetDisplay()}
// 和:{GetDisplay()}
// 积:{GetDisplay()}
// 是否相等:{True/False}
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C# 在线编译器