通过VBNETVB程序员终于拥有了全部面向对象的特征其中之一就是程序员以创建抽象类虽然抽象类在编程中的作用常被过高估计但抽象类确实提供了不少开发可行性
一段时间以来VB程序员都在要求微软向他们提供全面的备受C++及JAVA程序员推崇的面向对象的特性虽然有少部份与OOP相关的特征已被添加到旧的版本上但程序员还得等待VBNET将实际意义上的OOP添加到VB上去通过OOP你可以创建抽象类 虽然大家都对它寄予了厚望但令人惭愧的是抽象类仅仅只能给程序员提供更多的开发可行性而已
阅读本文您需要具备一定的面向对象以及VBNET的相关知识
很容易解释什么是抽象类? 抽象类即是不能被实例化的类而且你不能够在自己的程序里通过这种类来生成一个对象
你也许会认为不能被实例化的类是没多大用处的事实上在某些环境下 抽象类是非常有用的你可以把它作为一个基础类以此为基类创建新的类 在对功能要求不高的环境下生成的类会向你提供一个规定的启始点通过这个点你可以推导出非抽象类
在此假设一个要用抽象类的程序设计假设图形程序提供了大量的drawing类:比如圆三角曲线等等所有这些作drawing类都有某个共同的特性比如位置大小色彩删除等属性其它的类成员比如描绘图形的方法就不同于每个单独的类因此这样为利用抽象类创造了一个理想的环境
在抽象类中你需要定义所有drawing类都需要的全部通用类成员 因为drawing类不响应任何图形但是当把它作为shapespecific drawing类中的base类你需要确认所有这些非抽象类拥有最基本的功能
创建抽象类
对抽象类的定义很简单只要在定义域里加入关键字MustInherit如
Public MustInherit class MyAbstract class
End class
除开要包含关键字之外 抽象类的定义与非抽象类的定义没什么两样 抽象类包含了从其它类承继而来的属性及方法等等但是在抽象类中定义的类成员(属性及方法)是如何与衍生类中的定义元素产生联系的呢?在此并没有复杂的规则但你作出的决定是与你所拥有的类的性能及它将衍生出来的 类所密切相关
你有三个选择
抽象类中已有的功能比如属性方法等在衍生类中可以被重载实现这一功能只要在成员定义中输入Overridable关键字如
Public Overridable Sub Move(NewX As Integer NewY As Integer)
End Sub
为重载abstract base 类中的成员衍生类在执行语句中须使用Overrides关键字段如
Public Overrides Move(NewX As Integer NewY As Integer)
End Sub
抽象类中已有的功能不能在衍生类中重载即是衍生类必须使用抽象类定义的成员如果你在抽象类中不使用任何特殊字段来定义任一成员将会产生该缺省以下代码定义了抽象类中的Xpos属性衍生类必须使用该属性因为该属性不能被重载如
Public Property XPos() As Integer
End Property
利用MustOverride关键字来定义抽象类成员该成员可以在衍生类中重载以下举例说明了衍生类必须执行名为GetObjectAt()的方法
Public MustOverride Function GetObjectAt(X As Integer Y As Integer) As Object
请注意MustOverride成员不需要End Sub 或End Function语句使用MustOverride最方便的地方在于它不仅规定了成员的名称同样也规定了成员的符号先前的例子要求任一衍生类都需定义名称为GetObjectAt()的方法因此会产生两种类型的整型变量以及返回一个类型对象该方法是在衍生类中的执行是完全根据程序员的指令要求通过MustOverride字段说明的方法一些时候也被称为abstract 成员
抽象类与接口
如果你熟悉接口的相关知识你会认为抽象类与它是如此相似事实上只是一部份类似定义仅含有抽象成员的抽象类基本上是与接口的定义相同的因为你已经规定衍生类必须执行某个具有专用符号的成员另外抽象类具有其它的功能是接口无法实现的尤其是在定义非抽象类成员的基本功能薄?BR>
当你在认为抽象类或是接口都能如常运作时请谨记如下几点
除了从一个类(抽象或非抽象) 派生出来一个衍生类可以执行多个接口
从抽象类派生出来的子类同样能够执行一个或多个接口这要依你的项目而定你可以只用一个抽象类或多个接口或者抽象类和接口混合使用VB和NET在这项工作上提供了非常大的灵活性因此你可以通过不同的方式来达到你想要的结果底线是一些项目必须是通过抽象类来实现抽象类也许会被认为是一种非常专业的编程方法它可帮程序员减少工作量并且可以生成更简便功能更强大的程序
实际操作中使用抽象类
设想一下你正在为一家大公司开发一个新的员工数据库你的工作就是监督类的执行使雇员的基本情况与管理部门的要求相吻合同样 在区分公司分支机构的要求时也提供更大的便利
基本要求如下:
抽象类里有姓名雇用时间等属性这些属性不会被重载
因为大多数雇员来自美国因此在抽象类里执行退休ID以运行社会保障号码国外分公司将会利用不同的方式来鑒别雇员的退休ID因此该属性会在衍生类里重载以便单个分支机构分别执行
名称为补偿金的方法不会引起争议然后会返回一个含有雇员补偿金细节的类型对象因为不同分公司都规定不同的补偿金薪金佣金红利等因此灵活的执行这些对象是很有必要的由此会产生一个抽象方法
由此而产生的抽象类的代码称为EmployeeBase会在第一栏里显示
位于法国的分公司的程序员用EmployeeBase类作为EmployeeFrance类的基类与当地雇员记录软件合作使用因此衍生类需要承继名称及雇用日期等字段更多的是在EmployeeBase 类中的RetirementID成份适合运用在法国因此新类不会重载该成份程序员做的所有这些工作是为了执行abstract Compensation member 的重载
但是在英国 RetirementID 属性不适用于该地因此衍生类将会重载该成员同样的也会重载Compensation 成员