Visual Basic.NET+SQL Server全程指南
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

实例3-8 类的多态性

该实例实现步骤如下。

1 创建模块

在本章的项目chapter3下,右键该项目名下面的文件夹“类及对象”,在弹出菜单中选择“添加”→“模块”菜单命令,在弹出的对话框中输入模块名称MulModule,单击“添加”按钮完成模块的创建。

2 添加代码

双击MulModule.vb进入该模块的代码编辑窗口,向其中添加代码3-17中的代码。在代码3-17中,TestPoly过程演示了基于继承的多态性。ShowTax过程接受BaseTax类型的名为Item的参数,但还可以传递从BaseTax类派生的任何类,如CityTax。这种设计的优点在于可添加从BaseTax类派生的新类,而不用更改ShowTax过程中的客户端代码。

代码3-17 MulModule.vb

        01. Const StateRate As Double = 0.053 ' %5.3 州税率
        02. Const CityRate As Double = 0.028  ' %2.8 城市税率
        03. Public Class BaseTax
        04.     Overridable Function CalculateTax(ByVal Amount As Double) As Double
        05.         Return Amount * StateRate ' 计算州税额
        06.     End Function
        07. End Class
        08. Public Class CityTax
        09.     Inherits BaseTax '继承BaseTax类
        10.     Private BaseAmount As Double
        11.     Overrides Function CalculateTax(ByVal Amount As Double) As Double
        12.         '重写BaseTax类的CalculateTax()方法,改变返回的值
        13.         BaseAmount = MyBase.CalculateTax(Amount)
        14.         Return CityRate * (BaseAmount + Amount) + BaseAmount
        15.         End Function
        16. End Class
        17. Sub TestPoly()
        18.         Dim Item1 As New BaseTax() '实例化BaseTax()类
        19.         Dim Item2 As New CityTax() '实例化CityTax()类
        20.         ShowTax(Item2, 22.74) '计算城市销售税
        21. End Sub
        22. Sub ShowTax(ByVal Item As BaseTax, ByVal SaleAmount As Double)
        23.         Dim TaxAmount As Double
        24.         TaxAmount = Item.CalculateTax(SaleAmount)
        25.         MsgBox("The tax is: " & Format(TaxAmount, "C"))
        26. End Sub
        27. Sub main()
        28.         TestPoly()
        29. End Sub

代码3-17执行步骤如下:

① 第1行和第2行代码定义两个常量分别为州税率和城市税率;

② 第3行到第7行代码定义一个基类BaseTax,其中第4行到第6行代码在该基类中定义了一个方法,用于实现计算州税额并返回;

③ 第8行和第9行代码定义一类CityTax并继承基类BaseTax;

④ 第11行到第15行代码重写基类中的方法,实现计算在加上州税额之后的销售额的城市税额并返回;

⑤ 第17行到第21行代码定义一个方法,用于实例化上面两个类,调用ShowTax()方法;

⑥ 第22行到第26行代码定义ShowTax()方法,其中第24行代码调用派生类的方法计算出销售税额。在这里注意方法ShowTax()中的第一个参数定义的类型为BaseTax,而在第20行代码中调用ShowTax()方法是赋给它的第一个参数的值为派生类CityTax的实例,即指定一个CityTax对象将继续一个扩展转换。

3 运行结果

按F5键,运行程序,弹出如图3-9所示对话框。

图3-9 实例3-8运行结果

3.3.6 重载、重写和隐藏

1.重载

重载是在一个类中用相同的名称、不同的参数类型创建一个已有的过程、实例构造函数或属性。重载定义时使用关键字Overloads。

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

        Overloads Sub Display(ByVal theChar As Char)
        '添加显示字符型数据的代码
        End Sub
        Overloads Sub Display(ByVal theInteger As Integer)
        '添加显示整型数据的代码
        End Sub
        Overloads Sub Display(ByVal theDouble As Double)
        '添加显示双精度浮点型数据的代码
        End Sub

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

        Sub DisplayChar(ByVal theChar As Char)
        '添加显示字符型数据的代码
        End Sub
        Sub DisplayInt(ByVal theInteger As Integer)
        '添加显示整型数据的代码
        End Sub
        Sub DisplayDouble(ByVal theDouble As Double)
        '添加显示双精度浮点型数据的代码
        End Sub

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

        Display("9"C) '调用字符型Display方法.
        Display(9)   '调用整型Display方法.
        Display(9.9R) '调用双精度型Display方法.

在运行时,VB.NET根据指定参数的数据类型调用正确的过程。

下面论述一下重载规则。

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

· 应用于成员或成员参数的修饰符,如ByVal或ByRef。

· 参数名。

· 过程的返回类型。

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

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

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

Overloads和Shadows(隐藏)修饰符不能同时被同一个属性或方法使用。

下面以实例说明重载的运用。