导航

重载(overloads)与重写(override)的概念!

Posted on 2006-12-06 19:29  madduck  阅读(2301)  评论(3编辑  收藏  举报

重载引自:http://msdn2.microsoft.com/zh-cn/library/1z71zbeh(vs.80).aspx
重写引自:http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/csref/html/vclrfoverridepg.asp

重载属性和方法 

重载是在一个类中用相同的名称但是不同的参数类型创建一个以上的过程、实例构造函数或属性。

重载用法

当对象模型指示对于在不同数据类型上进行操作的过程使用同样名称时,重载非常有用。例如,可显示几种不同数据类型的类可以具有类似如下所示 Display 过程:

Visual Basic
Overloads Sub Display(ByVal theChar As Char)
' Add code that displays Char data.
End Sub
Overloads Sub Display(ByVal theInteger As Integer)
' Add code that displays Integer data.
End Sub
Overloads Sub Display(ByVal theDouble As Double)
' Add code that displays Double data.
End Sub

如果不使用重载,那么即使每个过程执行相同的操作,也需要为它们创建不同的名称,如下所示:

Visual Basic
Sub DisplayChar(ByVal theChar As Char)
' Add code that displays Char data.
End Sub
Sub DisplayInt(ByVal theInteger As Integer)
' Add code that displays Integer data.
End Sub
Sub DisplayDouble(ByVal theDouble As Double)
' Add code that displays Double data.
End Sub

因为重载提供了对可用数据类型的选择,所以它使得属性或方法的使用更为容易。例如,可以用下列任一代码行调用前面讨论过的重载 Display 方法:

Visual Basic
' Call Display with a literal of type Char.
Display("9"c)
' Call Display with a literal of type Integer.
Display(9)
' Call Display with a literal of type Double.
Display(9.9R)

在运行时,Visual Basic 根据指定参数的数据类型来调用正确的过程。

Note注意

重载、重写和隐藏是很容易混淆的类似概念。有关更多信息,请参见介绍 Visual Basic 中的对象

重载规则

用同样名称添加两个或更多属性或方法可以创建类的一个重载成员。除了重载派生成员,每一个重载成员必须具有不同的参数列表。当重载属性或过程时,下面的项不能用作区分特征:

  • 应用于成员或成员参数的修饰符,如 ByValByRef

  • 参数名

  • 过程的返回类型

重载时关键字 Overloads 是可选的,但如果任一重载成员使用了该 Overloads 关键字,则其他所有同名重载成员也必须指定该关键字。

派生类可以用具有相同参数和参数类型的成员重载继承成员,该过程称为“按名称和签名隐藏”。如果按名称和签名隐藏时使用了 Overloads 关键字,将使用成员的派生类实现而不是基类中的实现,并且该成员的所有其他重载对于派生类的实例都可用。

如果用一个具有相同参数和参数类型的成员重载继承成员时省略 Overloads 关键字,则该重载称为“按名称隐藏”。按名称隐藏替换成员的继承实现,使所有其他重载对于派生类及由其派生的类的实例都不可用。

OverloadsShadows 修饰符不能同时被同一个属性或方法所使用。

示例

下面的示例创建接受美元金额的 StringDecimal 表示形式并返回包含销售税的字符串的重载方法。

使用此示例创建重载方法

  1. 打开新项目,添加名为 TaxClass 的类。

  2. TaxClass 类中添加下面的代码。

    Visual Basic
    Public Class TaxClass
        Overloads Function TaxAmount(ByVal decPrice As Decimal, _
        ByVal TaxRate As Single) As String
        TaxAmount = "Price is a Decimal. Tax is $" & _
        (CStr(decPrice * TaxRate))
        End Function
        Overloads Function TaxAmount(ByVal strPrice As String, _
        ByVal TaxRate As Single) As String
        TaxAmount = "Price is a String. Tax is $" & _
        CStr((CDec(strPrice) * TaxRate))
        End Function
        End Class
        
  3. 向窗体中添加下面的过程。

    Visual Basic
    Sub ShowTax()
        ' 8% tax rate.
        Const TaxRate As Single = 0.08
        ' $64.00 Purchase as a String.
        Dim strPrice As String = "64.00"
        ' $64.00 Purchase as a Decimal.
        Dim decPrice As Decimal = 64
        Dim aclass As New TaxClass
        'Call the same method with two different kinds of data.
        MsgBox(aclass.TaxAmount(strPrice, TaxRate))
        MsgBox(aclass.TaxAmount(decPrice, TaxRate))
        End Sub
        
  4. 向窗体中添加按钮,并从该按钮的 Button1_Click 事件调用 ShowTax 过程。

  5. 运行该项目并单击窗体上的该按钮,以测试重载 ShowTax 过程。

在运行时,编译器选择与所用参数匹配的适当重载函数。单击该按钮时,首先将使用字符串类型的 Price 参数调用重载方法,并显示信息:“Price is a String.Tax is $5.12”。第二次将使用 Decimal 类型的值调用 TaxAmount,并显示信息“Price is a Decimal.Tax is $5.12”。

可重载运算符(C# 编程指南) 

C# 允许用户定义的类型通过使用 operator 关键字定义静态成员函数来重载运算符。但不是所有的运算符都可被重载,下表列出了不能被重载的运算符:

 
运算符 可重载性

+-!~++--truefalse

可以重载这些一元运算符。

+, -, *, /, %, &, |, ^, <<, >>

可以重载这些二进制运算符。

==, !=, <, >, <=, >=

比较运算符可以重载(但请参见本表后面的说明)。

&&, ||

条件逻辑运算符不能重载,但可使用能够重载的 &| 进行计算。

[]

不能重载数组索引运算符,但可定义索引器。

()

不能重载转换运算符,但可定义新的转换运算符(请参见 explicitimplicit)。

+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=

赋值运算符不能重载,但 += 可使用 + 计算,等等。

=.?:->newissizeoftypeof

不能重载这些运算符。

Note注意

比较运算符(如果重载)必须成对重载;也就是说,如果重载 ==,也必须重载 !=。反之亦然,<> 以及 <=>= 同样如此。

重写override

使用 override 修饰符来修改方法、属性、索引器或事件。重写方法提供从基类继承的成员的新实现。由重写声明重写的方法称为重写基方法。重写基方法必须与重写方法具有相同的签名。

不能重写非虚方法或静态方法。重写基方法必须是虚拟的、抽象的或重写的。

重写声明不能更改虚方法的可访问性。重写方法和虚方法必须具有相同的访问级修饰符

不能使用下列修饰符修改重写方法:

new   static    virtual   abstract

重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且重写属性必须是虚拟的、抽象的或重写的。

有关访问基类成员的更多信息,请参见 7.5.8 基访问

有关重写方法的更多信息,请参见 10.5.4 重写方法

示例

请参见 virtual 关键字的示例。

从具有重写方法的派生类中,仍然可以通过使用 base 关键字来访问同名的重写基方法。例如,如果有虚方法 MyMethod() 和派生类上的重写方法,就可以通过下列调用从派生类访问此虚方法:

base.MyMethod()

将此方法与使用范围解析运算符 (::) 和基类名的 C++ 方法进行比较,例如:

My_Base_Class_Name::MyMethod()

示例

在该示例中,有一个基类 Square 和一个派生类 Cube。因为立方体的面积是六个正方形的面积之和,因此可以通过调用基类上的 Area() 方法来计算。

// cs_override_keyword.cs
// Calling overriden methods from the base class
using System;
class TestClass
{
public class Square
{
public double x;
// Constructor:
public Square(double x)
{
this.x = x;
}
public virtual double Area()
{
return x*x;
}
}
class Cube: Square
{
// Constructor:
public Cube(double x): base(x)
{
}
// Calling the Area base method:
public override double Area()
{
return (6*(base.Area()));
}
}
public static void Main()
{
double x = 5.2;
Square s = new Square(x);
Square c = new Cube(x);
Console.WriteLine("Area of Square = {0:F2}", s.Area());
Console.WriteLine("Area of Cube = {0:F2}", c.Area());
}
}

输出

Area of Square = 27.04
Area of Cube = 162.24