Fortran 代码实现
! 定义基类
module base_module
implicit none
type, abstract :: base_type
contains
procedure(abstract_method), deferred :: method
end type base_type
abstract interface
subroutine abstract_method(self)
import base_type
class(base_type), intent(inout) :: self
end subroutine abstract_method
end interface
end module base_module
! 定义子类1
module child1_module
use base_module
implicit none
type, extends(base_type) :: child1_type
contains
procedure :: method => child1_method
end type child1_type
contains
subroutine child1_method(self)
class(child1_type), intent(inout) :: self
print *, 'Child1 method implementation'
end subroutine child1_method
end module child1_module
! 定义子类2
module child2_module
use base_module
implicit none
type, extends(base_type) :: child2_type
contains
procedure :: method => child2_method
end type child2_type
contains
subroutine child2_method(self)
class(child2_type), intent(inout) :: self
print *, 'Child2 method implementation'
end subroutine child2_method
end module child2_module
! 主程序
program polymorphism_example
use base_module
use child1_module
use child2_module
implicit none
type(base_type), pointer :: base_ptr
type(child1_type) :: child1_obj
type(child2_type) :: child2_obj
base_ptr => child1_obj
call base_ptr%method()
base_ptr => child2_obj
call base_ptr%method()
nullify(base_ptr)
end program polymorphism_example
实现原理
- 抽象基类和虚函数:在 Fortran 中,通过定义一个包含抽象过程(使用
abstract
和 deferred
关键字)的抽象基类。抽象过程没有具体实现,需要在子类中重写。
- 子类重写:每个子类继承自抽象基类,并提供对基类中抽象过程的具体实现。在子类定义中,使用
procedure :: method => childX_method
这种方式将基类的抽象方法绑定到子类的具体实现。
- 运行时多态:通过基类指针指向不同子类的对象,在运行时根据指针实际指向的对象类型来决定调用哪个子类的重写方法。当调用
base_ptr%method()
时,Fortran 运行时系统会根据 base_ptr
实际指向的是 child1_type
还是 child2_type
对象,来调用相应的 child1_method
或 child2_method
。
优势
- 代码灵活性:允许在不修改现有代码的情况下添加新的子类,只要新子类遵循基类的接口,程序就可以正确处理这些新类型的对象。
- 可维护性:将通用部分放在基类中,特定行为在子类中实现,使得代码结构更加清晰,易于维护和扩展。
- 提高代码复用性:基类中定义的通用成员和过程可以被所有子类复用,减少了重复代码。