操作符一般用于系统预定义的数据类型。如果在类中定义操作符,就称为操作符重载。
操作符重载包括一元操作符重载和二元操作符重载,以及用户定义的数据类型转换。
如果有一个复数Complex 类对一元操作符“++”重载,可以写成:
1 public static Complex operator ++(Complex a)2 3 {4 5 .......................................................6 7 }
如果是对二元操作符“+”重载可以写成:
1 public static Complex operator +(Complex a,Complex b) 2 { 3 ............... 4 }
一元操作符有一个参数,二元操作符有两个参数,重载操作符的开始必须以public static 修饰。可以重载的操作符包括:
一元操作符:+、-、!、~、++、--、true、false。
二元操作符:+、-、*、/、 %、 &、 |、^、<<、>>、==、!=、 >、<、 >=、<=。
下面的操作符要求同时重载、不能只重载其中的一个:
一元操作符:true和false。
二元操作符:==和!= >和< >=和<=。
操作符的作用:
操作符重载给类的一些操作带来一些方便,俩个复数的实部相加运算可以写成:
1 public static double Add(Complex a,Complex b)2 3 {4 5 return a.r+b.r6 7 }
这样的写发不够简洁,并且类的成员修饰符不为public时就不能这样直接操作了。
4.7操作符重载的实现-------------------------------------->>>>>>>>>>>>>>>>>>
先新建一个类:Complex.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Application27 7 { 8 class Complex 9 {10 double r, v;11 public Complex(double r, double v)12 {13 this.r = r;14 this.v = v;15 16 }17 //二元操作符“+”重载18 public static Complex operator +(Complex a, Complex b) { return new Complex(a.r + b.r, a.v + b.v); }19 20 //一元操作符“-”重载21 public static Complex operator -(Complex a)22 {23 return new Complex(-a.r, -a.v);24 25 }26 27 //一元操作符“++”重载28 public static Complex operator ++(Complex a)29 {30 double r = a.r + 1;31 double v = a.v + 1;32 return new Complex(r,v);33 34 }35 public void Print()36 {37 Console.Write(r+" + " +v+ "i\n");38 }39 40 }41 }
然后在主程序中实现:Test.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Application27 7 { 8 class Test 9 {10 public static void Main()11 {12 Complex a = new Complex(3, 4);13 Complex b = new Complex(5,6);14 15 Complex c = -a;16 c.Print();17 18 Complex d = a + b;19 d.Print();20 a.Print();21 22 Complex e = a++; //先赋值后++23 a.Print();24 e.Print();25 26 Complex f = ++a; //先++后赋值27 a.Print();28 f.Print();29 }30 }31 }
在操作符重载中,返回值往往需要新建(new)一个新建的Complex对象。
另外一个种操作符重载类型是用户定义的数据类型转换,它实现不同类型之间的转换,包括显示转换和隐式转换两种方式。
编程中往往需要将一个类型转换成另外一个类型。例如将Int转换成double, 他们是系统已经预定义的类型,编译器知道如何来执行他们的转换,具体内容以后在说吧。
如果他们中间有的类型不是编译器预定义的类型,编译器将不知道如何执行转换,解决的方法是使用用户定义的数据类型转换。
如果转换过程不会因丢失数据而出现异常,就采用隐式转换。如果转换过程有可能丢失数据,就要采用显示转换。
隐式类型转换的写法如下:
1 //隐式转换如下2 public static implicit operator Square(double s)3 {4 ..................5 }
要实现double向Square 转换功能,用关键字explicit进行显式类型转换:
1 public static explicit operator double (Square a)2 {3 ....................4 }
4.8 用户定义的数据类型转换
我们用实例来具体的进行数据类型的转换,首先我们先建立一个类,Square.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Application29 7 { 8 class Square 9 { 10 private double Side; 11 public Square(int a) 12 { 13 Console.WriteLine("Int 类型参数构造函数"); 14 Side = (double)a; 15 } 16 public Square(double a) 17 { 18 Console.WriteLine("double类型参数构造函数"); 19 Side = a; 20 } 21 //重写object类的Tostring()方法 22 public override string ToString() 23 { 24 Console.WriteLine("重写object类的ToString()方法"); 25 // return base.ToString(); 26 return this.Side.ToString(); 27 } 28 //重载“+”操作符,参数为两个Square类 29 public static Square operator +(Square x, Square y) 30 { 31 Console.WriteLine("重载+操作符,参数为两个Square类"); 32 return new Square(x.Side+y.Side); 33 } 34 //重载“+”操作符,参数一个为Square类,另外一个为double类型 35 public static Square operator +(Square x, double y) 36 { 37 Console.WriteLine("重载+操作符,参数一个为Square类,另外一个为double类型"); 38 return new Square(x.Side+y); 39 } 40 41 //重载“+”操作符,参数一个为Square类,另一个为int类型 42 public static Square operator +(Square x, int y) 43 { 44 Console.WriteLine("重载+操作符,参数一个为Square类,另一个为double类型"); 45 return x + (double)y; //调用上面的重载“+”操作符 46 } 47 48 //隐式类型转换,实现double类型转换为Square 49 public static implicit operator Square(double s) 50 { 51 Console.WriteLine("隐式类型转换,实现double类型转换为Square"); 52 return new Square(s); 53 54 } 55 //隐式类型转换,实现int类型转换为Square 56 public static implicit operator Square(int s) 57 { 58 Console.WriteLine("隐式类型换换,实现int 类型转换为Square"); 59 return new Square((double)s); 60 } 61 //重载“==”操作符 62 public static bool operator ==(Square x, Square y) 63 { 64 Console.WriteLine("重载==操作符,俩个参数都为Square类"); 65 return x.Side == y.Side; 66 } 67 //重载“!=”操作符 68 public static bool operator !=(Square x, Square y) 69 { 70 Console.WriteLine("重载!=操作符,两个参数都为square类"); 71 return !(x==y); //调用前面的操作符“==”操作符 72 } 73 //重载“==”和“!=”的同时还要重载object类的GetRashCode()和Equals(),否则编译器会发出警告 74 //也可以不重写这两个方法,这时对运行结果没有影响 75 public override bool Equals(object o) 76 { 77 return this == (Square)o; 78 } 79 public override int GetHashCode() 80 { 81 return (int)Side; 82 } 83 //重载“>”操作符 84 public static bool operator >(Square x, Square y) 85 { 86 Console.WriteLine("重载>操作符,这个两个参数都为Squarel类"); 87 return x.Side > y.Side; 88 } 89 //重载“<”操作符 90 public static bool operator <(Square x, Square y) 91 { 92 Console.WriteLine("重载 <操作符,两个参数都为square类"); 93 return x.side < y.side; 94 } 95 重载“<="”操作符" 96 public static bool operator x, square y) 97 { 98 console.writeline("重载<="操作符,两个参数都为Square类");" 99 (x="=" || y); 调用重载操作符“="=”和“<”100" }101 重载“> =”操作符102 public static bool operator >=(Square x, Square y)103 {104 Console.WriteLine("重载>=操作符,两个参数都为Square类");105 return (x > y) || (x == y); //调用重载操作符“==”和“>”106 }107 108 }109 110 } 操作符,两个参数都为square类");>
------------------在主程序中执行
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Application29 7 { 8 class Program 9 {10 static void Main(string[] args)11 {12 Square s1 = new Square(10);13 Square s2 = new Square(20);14 Square s3 = s1 + s2; //调用operator+(Square,Square)15 Console.WriteLine(s3);//调用重写object类的ToString()方法16 Console.WriteLine(s3 + 15);//调用重写的operator+(Square,int)以及ToString()17 Console.WriteLine(s3 + 1.5);//调用重写operator+(Square,double)和ToString()18 s3=10; //调用隐式转换public Static implicit operator Square(int )19 Console.WriteLine(s3);20 Square s4 = 10;21 Console.WriteLine(s1==s4); //调用==操作符22 Console.WriteLine(s1!=s4); //调用!=操作符23 Console.WriteLine(s1>s2); //调用>操作符24 Console.WriteLine(s1
执行结果如下:
分析上面:
Square与double和int之间有两个隐式转换,从double以及int的转换过程不会因丢失数据而出现异常,所以采用了隐式转换。
Square类默认的基类是Object类,所以可以重载Objcet类的ToString方法。Writeline方法默认的参数为String对象,所以在输出之前要调用ToString方法,将参数转换为String类型。