Written by rdc
多态性是面向对象程序中的强大工具。多项式方法(Sub或Function)的行为取决于对象的定义。例如,动物对象可能会发出一种方法,发出狗的吠声和猫的喵。FreeBasic在版本0.90.0之前不支持真正的多态。但是,您可以使用方法指针来模拟多态方法。
多态方法是具有相同类型和参数列表的子例程或函数,但在绑定到不同对象时的行为不同。一个动物物体可能会有一个Speak方法,它将为一只狗发出一只树皮和一只猫的喵。由于FreeBasic还没有类,所以您无法实现真正??的多态方法,但您可以使用方法指针来模拟行为。
以下列表显示了一些定义和扩展类型声明:
#define isdog 1
#define iscat 2
Type animal
Public:
speak As Sub()
Declare Constructor (anid As Integer)
End Type
#define被传递给构造函数,以指示正在创建什么类型的对象。说As As()定义定义方法指针。如你所见,两个不同子例程的地址将被传递给说话方法指针。以下列表显示了不同的说明子程序和构造方法:
'Speak method for dog object
Sub Bark()
Print "Woof!"
End Sub
'Speak method for cat object
Sub Meow()
Print "Meow!"
End Sub
'Set the proper method pointer based on animal id
Constructor animal(anid As Integer)
If anid = isdog Then
this.speak = @Bark
ElseIf anid = iscat Then
this.speak = @Meow
End If
End Constructor
如果对象是一个狗,则将调用Bark子例程,如果对象是一个猫,则将调用Meow子例程。你可能会想知道为什么你不能只是重载方法?对于重载方法,类型和参数列表必须是唯一的,其中在多态方法中,类型和参数列表必须相同。由于Bark和Meow具有相同的参数列表,因此无参数,因此无法重载该方法。
构造函数代码是程序决定使用什么方法调用的地方。如果anid等于isdog,则Speak方法指针将被设置为Bark子例程的地址。如果anid等于iscat,则Speak将被设置为Meow子例程的地址。address @的地址用于将Bark和Meow的地址传递给Speak指针。
this 对象引用是一个隐藏的参数,它被传递给引用类型的构造方法,在这种情况下,它是动态的。您可以使用它来引用类型中的内部变量。
唯一需要做的是创建和初始化对象:
'Create a dog and cat object
Dim myDog As animal = isdog
Dim mycat As animal = iscat
这里myDog和myCat是使用传递给构造函数的相应标志创建的,以便可以设置正确的引用。创建对象后,您可以调用每个对象的说话方法。
'Have the animals speak
Print "My dog says ";
myDog.speak()
Print "My cat says ";
myCat.speak()
请注意,您正在调用相同的方法,但输出不同:
My dog says Woof!
My cat says Meow!
这是多态方法的本质。
这是完整的程序列表:
'Simulated Polymorphism Using Method Pointers
'Richard D. Clark
'Requires the CVS version of FreeBasic
'**********************************************
#define isdog 1
#define iscat 2
Type animal
Public:
speak As Sub()
Declare Constructor (anid As Integer)
End Type
'Speak method for dog object
Sub Bark()
Print "Woof!"
End Sub
'Speak mehod for cat object
Sub Meow()
Print "Meow!"
End Sub
'Set the proper method pointer based on animal id
Constructor animal(anid As Integer)
If anid = isdog Then
this.speak = @Bark
ElseIf anid = iscat Then
this.speak = @Meow
End If
End Constructor
'Create a dog and cat object
Dim myDog As animal = isdog
Dim mycat As animal = iscat
'Have the animals speak
Print "My dog says ";
myDog.speak()
Print "My cat says ";
myCat.speak()
Sleep
End
通过使用抽象/虚拟方法通过继承使用多态性(现在支持的功能),上一个转换为fbc版本0.90.0或更高版本的示例:
'Requires FreeBasic version >= 0.90.0
'Base-type animal
Type animal Extends Object
Declare Abstract Sub speak ()
End Type
'Derived-type dog
Type dog Extends animal
Declare Virtual Sub speak () Override
End Type
'Speak method for dog object
Virtual Sub dog.speak ()
Print "Woof!"
End Sub
'Derived-type cat
Type cat Extends animal
Declare Virtual Sub speak () Override
End Type
'Speak mehod for cat object
Virtual Sub cat.speak ()
Print "Meow!"
End Sub
'Create a dog and cat as dynamic object through animal pointer
Dim myDog As animal Ptr = New dog
Dim mycat As animal Ptr = New cat
'Have the animals speak
Print "My dog says ";
myDog->speak()
Print "My cat says ";
myCat->speak()
Sleep
'Delete the dynamic objects
Delete myDog
Delete myCat