改变思路,从另一个角度使用多态

2008-04-09 04:40:50来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

  作者在写《傻瓜打表》部件时,原本想提供打印预览功能,因当时眼界较窄,所知道的只有一个方法实现打印预览: 定义一个 Object 变量(如:ObjPrn),用该变量替换程序中的与打印有关的语句中的 Printer 对象,打印时,首先设置

Set ObjPrn = Printer

预览时设置

Set ObjPrn = frmPreV.Picture1

  用上述方法虽然可以实现打印和预览,但是,显然对打印机和实现预览的图像控件的访问都是后期邦定的,这在效率上是不高的。打算使用多态技术,可是 Printer 对象和 Picturebox控件不是从一个类(VB中可引用的)派生的。因无法实现打印和预览的前期绑定,故没有提供打印预览功能。

  一天,当再次阅读VB帮助中的多态章节时,突然想到了一个方法,使用该方法,只要两个类具有相同的部分接口(方法、属性及参数),即便这两个类毫不相干,也可以通过变相用多态技术提供对这两个类的前期绑定。
多态是干什么的?

  MSDN说:多态意味着许多类可以提供同样的属性或者方法,而且调用者在调用这些属性或方法之前,不必知道某个对象属于什么类。
多态的意义之一就是,通过多态接口,对多个不同类的访问可以获得高效的前期绑定。

  一般来说,如果几个类具有部分相同的属性、方法,但却不是用多态接口实现的(例如Printer和Form),将不能提供类似多态的性能。
但是,“软件”正如其名字中的“软”,是一个灵活的、可塑的东西,我们可以改变思维模式,换一个角度:没有多态接口的两个类(如Printer、Picturebox)如同两个人不同父,不是兄弟;但我们可以让其子同娶一家之女(另外具有多态接口的两个类),其子为连襟,其儿媳为姐妹,而通过其儿媳访问其本人具有相同的路径。

  还以上例,其中的关键是:添加三个类,分别Printer之妻、Picturebox之妻、二女之父(在二女中要实现的、Printer和Picturebox共有的部分接口)。下面就用打印和预览为例,介绍该方法:

第一步、添加一个抽象类,在该类中定义共同的方法和属性。

  如果方法名称是VB关键字,可以修改(如Line方法,本例中改为pLine方法);如果参数形式不符合VB语法,也可作相应修改(如本例中Line方法的参数,应为"(X1, -(X2,Y2),Forcolor,BF",显然,在VB中的参数不能用这种形式;还有Print方法,打印参数之间、后面可以跟逗号、分号等,也要相应改变,并且不能提供全部原来Print方法功能) :
类名:IMyPrinter,为简化,示例中仅包含作为示例的接口。
Public Property Get CurrentX() As Single
End Property

Public Property Let CurrentX(ByVal RHS As Single)
End Property

Public Sub EndDoc()
End Sub

Public Property Get Font() As stdole.Font
End Property

Public Property Set Font(ByVal RHS As stdole.Font)
End Property

Public Sub PLine(ByVal X1 As Single, ByVal Y1 As Single, ByVal X2 As Single, _
      ByVal Y2 As Single, Optional ByVal HasB As Boolean = False, _
      Optional ByVal HasF As Boolean = False)
End Sub

Public Function ScaleX(ByVal Width As Single, Optional ByVal FromScale As Variant, _
      Optional ByVal ToScale As Variant) As Single
End Function

Public Function TextWidth(ByVal Str As String) As Single
End Function

Public Property Let Width(ByVal RHS As Long)
End Property

Public Property Get Width() As Long
End Property

Public Sub PPrint(Optional ByVal F0D1H2 As Integer = 0, Optional PrnInfo)
End Sub

第二步、添加两个类,实现该接口,并分别提供Printer对象和Picturebox控件相应的功能。

  下面仅以在Picturebox控件上实现该接口的类的部分代码作为示例:还需要添加一个实现预览的窗体(frmPreView),在上面添加一个Picturebox控件(pic)

类名:MyPic
Implements IMyPrinter
Dim frm As frmPreview
Private pic As PictureBox

Private Sub Class_Initialize()
 Set frm = New frmPreview
 Load frm
 Set pic = frm.pic
End Sub

Private Sub Class_Terminate()
 Set pic = Nothing
 Unload frm
 Set frm = Nothing
End Sub

Private Property Let IMyPrinter_CurrentX(ByVal RHS As Single)
 pic.CurrentX = RHS
End Property

Private Property Get IMyPrinter_CurrentX() As Single
 IMyPrinter_CurrentX = pic.CurrentX
End Property

Private Sub IMyPrinter_EndDoc()
 frm.Show vbModal
End Sub

Private Property Get IMyPrinter_Font() As StdFont
Dim F As StdFont
 Set F = New StdFont
 With pic.Font
  F.Size = .Size
  F.Name = .Name
  F.Size = .Size
  F.Bold = .Bold
  F.Italic = .Italic
  F.Strikethrough = .Strikethrough
  F.Underline = .Underline
  F.Weight = .Weight
 End With
Set IMyPrinter_Font = F
End Property

Private Property Set IMyPrinter_Font(ByVal RHS As StdFont)
 With pic.Font
  .Size = RHS.Size
  .Name = RHS.Name
  .Size = RHS.Size
  .Bold = RHS.Bold
  .Italic = RHS.Italic
  .Strikethrough = RHS.Strikethrough
  .Underline = RHS.Underline
  .Weight = RHS.Weight
 End With
End Property

Private Sub IMyPrinter_PLine(ByVal X1 As Single, ByVal Y1 As Single, ByVal X2 As Single, ByVal Y2 As Single, Optional ByVal HasB As Boolean = False, Optional ByVal HasF As Boolean = False)
 If HasF Then "本例中没有提供颜色选项
  pic.Line (X1, Y1)-(X2, Y2), , BF
 ElseIf HasB Then

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:用VB6轻松实现图片旋转

下一篇:用VB编写Flash图像浏览器