ZetCode

FreeBasic Virtual 关键字

最后修改日期:2025 年 6 月 16 日

FreeBasic 的 Virtual 关键字通过允许在派生类中重写方法来实现多态。它是 FreeBasic 面向对象编程的基础。虚拟方法提供运行时方法解析。

基本定义

在 FreeBasic 中,Virtual 将一个方法标记为可以在派生类中重写。当调用虚拟方法时,实际的实现将根据对象的类型在运行时确定。

虚拟方法在基类中声明,并可以使用 Override 关键字在派生类中重新定义。这实现了多态行为,其中相同的代码调用可以产生不同的结果。

简单的虚拟方法

此示例演示了基本的虚拟方法声明和重写。

virtual_basic.bas
Type Animal
    Declare Virtual Sub MakeSound()
End Type

Type Dog Extends Animal
    Declare Sub MakeSound() Override
End Type

Sub Animal.MakeSound()
    Print "Animal sound"
End Sub

Sub Dog.MakeSound()
    Print "Woof!"
End Sub

Dim As Animal Ptr a = New Dog
a->MakeSound()
Delete a

在这里,我们定义了一个具有虚拟 MakeSound 方法的 Animal 基类型。Dog 类型重写了此方法。当通过基类指针调用时,将执行派生类的实现。

带参数的虚拟方法

虚拟方法可以像普通方法一样接受参数。

virtual_params.bas
Type Shape
    Declare Virtual Function Area(w As Integer, h As Integer) As Integer
End Type

Type Rectangle Extends Shape
    Declare Function Area(w As Integer, h As Integer) As Integer Override
End Type

Function Shape.Area(w As Integer, h As Integer) As Integer
    Return 0
End Function

Function Rectangle.Area(w As Integer, h As Integer) As Integer
    Return w * h
End Function

Dim As Shape Ptr s = New Rectangle
Print "Area: "; s->Area(10, 20)
Delete s

此示例显示了一个带参数的虚拟方法。基类 Shape 提供了默认实现,而 Rectangle 用特定的计算重写了它。正确的版本在运行时被调用。

虚拟析构函数

虚拟析构函数确保派生类资源的正确清理。

virtual_destructor.bas
Type Base
    Declare Virtual Destructor()
    Declare Virtual Sub DoSomething()
End Type

Type Derived Extends Base
    Declare Destructor() Override
    Declare Sub DoSomething() Override
End Type

Destructor Base()
    Print "Base destructor"
End Destructor

Destructor Derived()
    Print "Derived destructor"
End Destructor

Sub Base.DoSomething()
    Print "Base doing something"
End Sub

Sub Derived.DoSomething()
    Print "Derived doing something"
End Sub

Dim As Base Ptr b = New Derived
b->DoSomething()
Delete b

此代码演示了虚拟析构函数的重要性。当通过基类指针删除派生类对象时,将首先调用派生类析构函数,然后调用基类析构函数。如果没有 virtual 关键字,则只会调用基类析构函数。

抽象虚拟方法

通过不提供实现,可以将虚拟方法设为抽象。

virtual_abstract.bas
Type Animal
    Declare Abstract Virtual Sub Speak()
End Type

Type Cat Extends Animal
    Declare Sub Speak() Override
End Type

Sub Cat.Speak()
    Print "Meow"
End Sub

Dim As Animal Ptr a = New Cat
a->Speak()
Delete a

在这里,Animal 声明了一个抽象的虚拟方法 Speak,派生类必须实现该方法。Cat 提供了实现。抽象方法创建了派生类必须遵循的接口。

多重继承

虚拟方法可以通过多个类继承级别进行工作。

virtual_multilevel.bas
Type Grandparent
    Declare Virtual Sub Greet()
End Type

Type Parent Extends Grandparent
    Declare Sub Greet() Override
End Type

Type Child Extends Parent
    Declare Sub Greet() Override
End Type

Sub Grandparent.Greet()
    Print "Hello from Grandparent"
End Sub

Sub Parent.Greet()
    Print "Hello from Parent"
End Sub

Sub Child.Greet()
    Print "Hello from Child"
End Sub

Dim As Grandparent Ptr g = New Child
g->Greet()
Delete g

此示例展示了通过三个继承级别进行的虚拟方法重写。当通过 Grandparent 指针调用时,将执行最派生的版本(Child 的实现)。这表明了深度继承层次结构中的多态性。

带返回值的虚拟方法

虚拟方法可以返回任何类型的返回值,包括用户定义类型。

virtual_return.bas
Type Result
    value As Integer
End Type

Type Calculator
    Declare Virtual Function Compute(a As Integer, b As Integer) As Result
End Type

Type Adder Extends Calculator
    Declare Function Compute(a As Integer, b As Integer) As Result Override
End Type

Function Calculator.Compute(a As Integer, b As Integer) As Result
    Dim r As Result
    r.value = 0
    Return r
End Function

Function Adder.Compute(a As Integer, b As Integer) As Result
    Dim r As Result
    r.value = a + b
    Return r
End Function

Dim As Calculator Ptr c = New Adder
Dim res As Result = c->Compute(5, 7)
Print "Result: "; res.value
Delete c

此代码演示了一个返回用户定义类型的虚拟方法。基类 Calculator 提供了默认实现,而 Adder 用特定功能重写了它。所有实现中的返回类型保持一致。

接口中的虚拟方法

在处理类似接口的模式时,虚拟方法至关重要。

virtual_interface.bas
Type IDrawable
    Declare Abstract Virtual Sub Draw()
End Type

Type Circle Extends IDrawable
    Declare Sub Draw() Override
End Type

Sub Circle.Draw()
    Print "Drawing a circle"
End Sub

Dim As IDrawable Ptr d = New Circle
d->Draw()
Delete d

此示例演示了如何在 FreeBasic 中使用虚拟方法来创建类似接口的行为。IDrawable 定义了一个 Circle 实现的契约。这种模式对于创建具有明确定义的行为的可插入组件很有用。

最佳实践

本教程通过实际示例介绍了 FreeBasic Virtual 关键字,展示了其在不同场景下的用法。虚拟方法实现了多态性,这是面向对象编程的基石。

作者

我的名字是 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 FreeBasic 教程