面向对象编程是一种开发模型,其本意是使用对象将零散的数据用更具象化的方式描述、表达。
这种开发模型有被滥用的趋势,但本身的实用性还是很强的,果壳精灵也支持基础的面向对象开发特性:构造、析构和继承。
面向对象编程的基本单位是类(Class),类本质上其实就是 Type 定义的结构体,在很多不完全面向对象的编程语言中,类都是结构体的扩展。
因此定义一个类的方法和定义一个结构体的方法是一样的,但是你可以指定这个类继承自哪一个父类,只需要在结构体名字后面加上【Extends】语句,再写上父类的名字即可:
Type T2D x As Long y As Long End Type Type T3D Extends T2D z As Long End Type
当一个类继承自另一个类时,这个类就具备了父类所有的【属性】和【方法】。
属性就是这个结构体内定义的变量,方法就是这个结构体内定义的函数。
例如上面的范例中,T3D 继承自 T2D,那么 T3D 这个类也具备了 x 和 y 两个属性。
因为继承的缘故,一些功能相似的代码可以归类整理,一些场景里用好了可以大幅降低代码行数。
这里展示一种比较经典的类结构:
Type 生命基础对象 HP As Long MP As Long 攻击力 As Long 防御力 As Long 移动速度 As Long 攻击速度 As Long 已死亡 As Boolean End Type Type NPC Extends 生命基础对象 // NPC 不受伤害,不能被击杀 Function 受到攻击(ByRef 伤害 As Long) As Boolean 伤害 = 0 Return false End Function End Type Type 怪物 Extends 生命基础对象 // 血量扣完了就死了 Function 受到攻击(ByRef 伤害 As Long) As Boolean HP = HP - 伤害 If HP <= 0 Then 已死亡 = true Return true Else Return false End If End Function End Type Type BOSS Extends 生命基础对象 已变身 As Boolean // 血量扣完了触发变身 Function 受到攻击(ByRef 伤害 As Long) As Boolean HP = HP - 伤害 If HP <= 0 Then If 已变身 = false Then // 给第二条血量,变身 HP = 10000000 已变身 = true Return false Else // 第二条命也被打死了 已死亡 = true Return true End If Else Return false End If End Function End Type Type 玩家 Extends 生命基础对象 装备名刀 As Boolean 名刀CD中 As Boolean // 血量扣完了触发变身 Function 受到攻击(ByRef 伤害 As Long) As Boolean HP = HP - 伤害 If HP <= 0 Then If 装备名刀 And (名刀CD中 = false) Then // 锁血不死 HP = 1 名刀CD中 = true Return false Else // 没有名刀,耶稣也救不了你 已死亡 = true Return true End If Else Return false End If End Function End Type
你看,如果我们每一个对象都要做完整的定义,代码会变的非常多,有了继承之后,相同特征可以合并到一个基类下面,实现了代码的分类合并。
继承还可以继承好几层,合理的构建数据模型,能够用最少的代码,写出最清晰的程序:
Type T1D x As Long End Type Type T2D Extends T1D y As Long End Type Type T3D Extends T2D z As Long End Type
构造函数就是一个类在创建的时候会自动执行,用于初始化类数据的函数,在类代码中定义一个名为【_Create】的子程序:
Type 类名字 ' 属性 Attr As Long ' 构造函数 Sub _Create() Me.Attr = 1234 End Sub End Type Function Main() As Long Dim a As 类名字 TracePrint a.Attr End Function
类的构造函数也可以添加一些参数,这样能更方便的初始化数据:
Type 类名字 ' 属性 Attr As Long ' 构造函数 Sub _Create(iVal As Long) Me.Attr = iVal End Sub End Type Function Main() As Long Dim a As 类名字(12345678) TracePrint a.Attr End Function
析构函数和构造函数类似,它会在这个类不再使用的时候自动调用,在一些必须用代码释放资源的情况下,这个机制非常管用。
Type 类名字 ' 属性 Attr As Long ' 构造函数(可添加参数) Sub _Create(iVal As Long) Me.Attr = iVal End Sub ' 析构函数 Sub _Destroy() MsgBox("类已释放") End Sub End Type Function Main() As Long Dim a As 类名字(12345678) TracePrint a.Attr End Function