1.运算符重载
通过运算符重载,可以对我们设计的类使用标准的运算符,例如+、-等。这称为重载,因为在使用特定的参数类型时,我们为这些运算符提供了自己的实现代码,其方式与重载方法相同,也是为同名方法提供不同的参数。
要重载运算符,可给类参加运算符类型成员(它们必须是static)。一些运算符有多种用途,因此我们还指定了要处理的多少个操作数,以及这些操作数的类型,一般情况下,操作数的类型与定义运算符的类相同,但也可以定义处理混合类型的运算符。
例如,考虑一个简单类型AddClass1,如下所示:
public class AddClass1 { public int val; }
这仅是int值得一个包装器,但可以用于说明原理,对于这个类,下面的代码不能编译:
AddClass1 op1 =new AddClass1(); op1.val= 3; AddClass1 op2 = new AddClass1(); op2.val=5; AddClass1 op3 = op1+op2;
其错误是+运算符不能应用于AddClass1类型的操作数,因为我们尚未定义要执行的操作。下面的代码则可执行,但无法得到预期结果:
AddClass1 op1 =new AddClass1(); op1.val= 3; AddClass1 op2 = new AddClass1(); op2.val=3; AddClass1 op3 = op1==op2;
其中,使用==运算符来比较op1和op2,看它们是否引用同一个对象,而不是验证它们的值是否相等。在上述代码中,即使op1.val和op2.val相等,op3也是false。
要重载+运算符,可使用如下代码:
public class AddClass1 { public int val; public static AddClass1 operator +(AddClass1 op1,AddClass1 op2) { AddClass1 returnVal= new AddClass1(); returnVal.val=op1.val+op2.val; return returnVal; } }
可以看出,运算符重载看起来与标准静态方法类似,但它们使用关键字operator和运算符本身,而不是一个方法名。现在可以成功使用+运算符和这个类,如下面的示例所示:
AddClass1 op3 =op1+op2;
重载所有的运算符都是一样的,一元运算符看起来也是类似的,但只有一个参数:
public class AddClass1 { public int val; public static AddClass1 operator -(AddClass1 op1) { AddClass1 returnVal= new AddClass1(); returnVal.val=-op1.val; return returnVal; } }
这两个运算符处理的操作数的类型与类相同,返回值也是该类型,但考虑下面的定义:
public class AddClass1 { public int val; public static AddClass3 operator +(AddClass1 op1,AddClass2 op2) { AddClass3 returnVal=new AddClass3(); returnVal.val=op1.val+op2.val; return returnVal; } } public class AddClass2 { public int val; } public class AddClass3 { public int val; }
考虑下面的代码就可以执行:
AddClass1 op1 = new AddClass1(); op1.val=5; AddClass2 op2 = new AddClass2(); op2.val=4; AddClass3 op3 =op1+op2;
要注意,如果把相同的运算符添加到AddClass2中,上面的代码就会失败,因为它弄不清要使用哪个运算符。因此,注意不要把签名相同的运算符添加到多个类中。
还要注意,如果混合了类型,操作数的顺序必须与运算符重载的参数顺序相同,如果使用了重载的运算符和顺序错误的操作数,操作就会失败。所以,不能像这样使用运算符:
AddClass3 op3 =op2+op1;
当然,除非提供了另一个重载运算符和倒序的参数:
public static AddClass3 operator +(AddClass2 op2,AddClass1 op1) { AddClass3 returnVal=new AddClass3(); returnVal.val=op1.val+op2.val; return returnVal; }