转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> VB.NET程序 >> 正文
改变思路,从另一个角度使用多态         ★★★★

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

作者:闵涛 文章来源:闵涛的学习笔记 点击数:821 更新时间:2009/4/23 14:58:35
  作者在写《傻瓜打表》部件时,原本想提供打印预览功能,因当时眼界较窄,所知道的只有一个方法实现打印预览: 定义一个 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
  pic.Line (X1, Y1)-(X2, Y2), , B
 Else
  pic.Line (X1, Y1)-(X2, Y2)
 End If
End Sub

Private Sub IMyPrinter_PPrint(Optional ByVal F0D1H2 As Integer = 0, Optional PrnInfo As Variant)
 Select Case F0D1H2 "该参数为0:跟分号;1:跟逗号;2:无符号
  Case 0
   If Not IsMissing(PrnInfo) Then
    pic.Print PrnInfo;
   End If
  Case 1
   If Not IsMissing(PrnInfo) Then
    pic.Print PrnInfo,
   End If
  Case 2
   If Not IsMissing(PrnInfo) Then
    pic.Print PrnInfo
   Else
    pic.Print
   End If
 End Select
End Sub

Private Function IMyPrinter_ScaleX(ByVal Width As Single, Optional ByVal FromScale As Variant, Optional ByVal ToScale As Variant) As Single
 IMyPrinter_ScaleX = pic.ScaleX(Width, FromScale, ToScale)
End Function

Private Function IMyPrinter_TextWidth(ByVal Str As String) As Single
 IMyPrinter_TextWidth = pic.TextWidth(Str)
End Function

Private Property Get IMyPrinter_Width() As Long
 IMyPrinter_Width = pic.Width
End Property

Private Property Let IMyPrinter_Width(ByVal RHS As Long)
 pic.Width = RHS
End Property

第三步、在主类模块定义如下变量

Private cIMyPrn As IMyPrinter
Private cPic As MyPic
Private cPrn As MyPrn

在主类模块Class_Initialize事件中,添加:

Set cPrn As New MyPrn
Set cIMyPrn = cPrn

在主类模块中,将原来有关打印语句中的Printer替换为cIMyPrn。在实现预览的方法中,添加:

Set cPic = New MyPic
Set cIMyPrn = cMyPic

修改特殊类型的语句(如Line、Print,方法名和参数形式已经改变,将其改为符合cIMyPrn语法的语句)

预览结束后:

Set cIMyPrn = cPrn
Set cPic = Nothing

  通过上面的方法,就可以用一个IMyPrinter变量,实现打印和预览的前期绑定当然,该方法未必是实现打印、预览的首选,还可以使用API方法,直接操纵设备场景来实现打印预览,但该方法的意义不在于此,其意义在于该方法拓展了VB中提供的多态技术的应用范围。
本文副标题中的所谓“高层次”不是作者层次高,而是编程方法和思路,不是面向底层、面向Win核心,而是在对象的高层、在编程语言和方法的较高层上实现多态。


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台