.NET中预定义接口的使用与实现
立即解锁
发布时间: 2025-08-26 01:57:31 阅读量: 2 订阅数: 11 


精通VB 2008与.NET 3.5平台编程
### .NET 中预定义接口的使用与实现
#### 1. 接口编程概述
在使用 Visual Basic 定义和实现自定义接口的过程中,我们逐渐熟悉了相关语法。接口编程可能需要一些时间来适应,但它是 .NET 框架的基础部分。无论开发何种类型的应用程序(如基于 Web 的应用、桌面 GUI 应用等),使用接口都是开发过程的一部分。接口在以下两种情况下非常有用:
- 当存在一个单一的继承层次结构,且只有部分派生类型支持某种共同行为时。
- 当需要对跨多个继承层次结构的共同行为进行建模时。
#### 2. 构建可枚举类型(IEnumerable 和 IEnumerator)
`System.Collections` 命名空间定义了 `IEnumerable` 和 `IEnumerator` 两个接口。当构建支持这些行为的类型时,可以使用 Visual Basic 的 `For Each` 构造来迭代其中包含的子项。
假设我们有一个名为 `CustomEnumerator` 的控制台应用程序项目,并添加了一个名为 `Garage` 的类,该类包含一组 `Car` 对象,存储在 `System.Array` 中:
```vb
' Garage contains a set of Car objects.
Public Class Garage
Private myCars() As Car = New Car(3) {}
Public Sub New()
myCars(0) = New Car("Fred", 40)
myCars(1) = New Car("Zippy", 60)
myCars(2) = New Car("Mabel", 0)
myCars(3) = New Car("Max", 80)
End Sub
End Class
```
我们希望使用 `For Each` 构造来迭代 `Garage` 对象的子项,以下是理想的逻辑:
```vb
' This seems reasonable...
Module Program
Sub Main()
Console.WriteLine("***** Info about my Cars *****")
Dim myCars As New Garage()
' Hand over each car in the collection?
For Each c As Car In myCars
Console.WriteLine("{0} is going {1} MPH", _
c.Name, c.Speed)
Next
Console.ReadLine()
End Sub
End Module
```
然而,编译器会提示 `Garage` 类不是“集合类型”。集合类型需要支持 `GetEnumerator()` 方法,该方法由 `System.Collections.IEnumerable` 接口定义:
```vb
' This interface informs the caller
' that the object's subitems can be enumerated.
Public Interface IEnumerable
Function GetEnumerator() As IEnumerator
End Interface
```
`GetEnumerator()` 方法返回一个指向 `System.Collections.IEnumerator` 接口的引用,该接口提供了遍历 `IEnumerable` 兼容容器中内部对象的基础设施:
```vb
Public Interface IEnumerator
' Advance to the next object in collection.
Function MoveNext() As Boolean
' Reset to first object in collection.
Sub Reset()
' Pluck out current object pointed to.
ReadOnly Property Current() As Object
End Interface
```
为了让 `Garage` 类型支持这些接口,我们可以将请求转发给 `System.Array`:
```vb
Public Class Garage
Implements System.Collections.IEnumerable
Private myCars() As Car = New Car(3) {}
Public Sub New()
myCars(0) = New Car("Fred", 40)
myCars(1) = New Car("Zippy", 60)
myCars(2) = New Car("Mabel", 0)
myCars(3) = New Car("Max", 80)
End Sub
Public Function GetEnumerator() As System.Collections.IEnumerator _
Implements System.Collections.IEnumerable.GetEnumerator
Return myCars.GetEnumerator()
End Function
End Class
```
更新后的 `Garage` 类型可以安全地在 `For Each` 构造中使用,用户还可以直接与 `IEnumerator` 类型交互:
```vb
Sub Main()
Console.WriteLine("***** Info about my Cars *****")
Dim myCars As New Garage()
' Iterate over subobjects.
For Each c As Car In myCars
Console.WriteLine("{0} is going {1} MPH", _
c.Name, c.Speed)
Next
' Get IEnumerable directly.
Dim iEnum As IEnumerator
iEnum = myCars.GetEnumerator()
iEnum.Reset()
iEnum.MoveNext()
Dim firstCar As Car = CType(iEnum.Current, Car)
Console.WriteLine("First car in collection is: {0}", firstCar.Name)
Console.ReadLine()
End Sub
```
由于通常只有 `For Each` 构造会直接操作 `IEnumerator` 接口,我们可以将 `GetEnumerator()` 定义为 `Private`,以隐藏该成员:
```vb
Private Function GetEnumerator() As System.Collections.IEnumerator _
Implements System.Collections.IEnumerable.GetEnumerator
Return myCars.GetEnumerator()
End Function
```
#### 3. 构建可克隆对象(ICloneable)
`System.Object` 定义了一个名为 `MemberwiseClone()` 的方法,用于获取当前对象的浅拷贝。对象用户不能直接调用该方法(因为它是受保护的),但对象本身可以在克隆过程中调用它。浅拷贝会逐字复制对象的每个字段数据。
假设我们有一个名为 `Point` 的类:
```vb
' A class named Point.
Public Class Point
' Public for easy access, feel free to add properties
' to wrap private data if you choose.
Public xPos, yPos As Integer
Public Sub New()
End Sub
Public Sub New(ByVal x As Integer, ByVal y As Integer)
xPos = x : yPos = y
End Sub
Public Overrides Function ToString() As String
Return String.Format("X = {0} ; Y = {1}", xPos, yPos)
End Function
End Class
```
当我们将一个引用类型赋值给另一个引用类型时,实际上只是重定向了引用在内存中指向的对象。例如:
```vb
Sub Main()
Consol
```
0
0
复制全文
相关推荐









