当你有这样的多态性时,关于一个对象需要考虑两件事:它的dynamic类型及其declared类型。这parameters
的组成部分test_mask
(base_mask
)被声明为
class(base_pars),pointer :: parameters
因此,这样的组件具有声明类型base_pars
.
来指针赋值
mask_test%parameters=>par_test
mask_test%parameters
具有相同的动态类型par_test
: test_pars
。它是声明类型的base_pars
不过,当我们关心它的组件和绑定时,声明的类型很重要。base_pars
确实没有whoami
.
那么,你需要一些已声明类型的东西par_test
。无需更改派生类型的定义,您可以使用select type
构造。
select type (pars => mask_test%parameters)
class is (par_test)
iostat=pars%whoami() ! pars of declared type par_test associated with mask_test%parameters
end select
也就是说,使用这种方法事情很快就会变得非常乏味。一直在使用select type
,区分众多的扩展类型,将是一个相当大的难题。另一种方法是确保声明的类型base_pars
有绑定whoami
。我们没有像上面那样改变主程序,而是改变模块base_pars_module
:
module base_par_modules
implicit none ! Encourage good practice
type,abstract,public :: base_pars
contains
procedure(whoami_if), deferred :: whoami
end type
interface
integer function whoami_if(this)
import base_pars ! Recall we're in a different scope from the module
class(base_pars) this
end function
end interface
end module
所以,我们有一个延迟绑定base_pars
随后被扩展类型中的绑定覆盖test_pars
. mask_test%parameters%whoami()
主程序中的函数是有效的,调用的函数是由动态类型提供的parameters
.
这里的两种方法都解决了声明类型的绑定问题parameters
。哪种最适合您的实际问题取决于您的整体设计。
如果您知道您的类型层次结构都与基本类型有足够的共同点(也就是说,所有类型都将提供whoami
绑定),那么采用第二种方法是有意义的。当您遇到奇怪的特殊情况时,请使用第一种方法,我建议这种情况应该很少见。