我试图理解Fortran 2003标准(或更高版本)中面向对象的概念 . 我对C有一些了解,所以我认为这两种语言之间有一些共同点,可以帮助我更好地理解它们 .
在C中,多态性是通过类派生和成员函数覆盖来完成的 . 一个定义了一个“抽象”基类,几乎所有的虚函数都被定义了 . 不同的派生类包含它们的实际实现 . 所以其他函数只需要基于“抽象”类进行编程 . 然后它们适用于所有派生类 .
我认为在Fortran中,OOP以类似的方式完成,但存在一些差异 . 在我看来,需要定义一个带有一些虚函数的基类型,就像C一样 . 其他函数/子例程应遵循基类型中的成员函数定义 . 这是解决所有扩展类型的函数/子例程重用的方法 .
我对如何编写这个想法没有更好的想法 . 这是我的第一次尝试:
type Basis
integer :: NBasis
contains
private
procedure :: DoNothing
generic, public :: Constructor => DoNothing
generic, public :: AllocateBasis => DoNothing
endtype Basis
type, extends(Basis) :: GridBasis
private
integer :: NGrid
contains
private
procedure :: ConstructorGrid1
procedure :: ConstructorGrid2
generic, public :: Constructor => ConstructorGrid1, ConstructorGrid2, ConstructorGrid3
procedure :: AllocateGridReal
procedure :: AllocateGridCplx
generic, public :: AllocateBasis => AllocateGridReal, AllocateGridCplx
endtype GridBasis
-
首先,如何在类型Basis中定义“AllocateBasis”,使其像“虚函数”一样工作,所有扩展类型必须定义自己的“AllocateBasis”版本?
-
其次,如何在GridBasis类型中定义“AllocateBasis”?这里的定义包含它的真实实现 .
-
第三,如何在GridBasis类型中使“AllocateBasis”成为重载函数?即存在真实版本和复杂版本,并且它们都被命名为“AllocateBasis”,具有实际或复杂的输入可分配数组 .
-
第四,NOPASS与PASS . 据我所知,如果设置了PASS,那么就会有一个指向该对象的显式指针 . 但是当NOPASS设定时,就没有这样的东西了 . 那么PASS是简化澄清的吗?
1 回答
首先是您的问题的一些评论/答案:
您可以声明类型绑定过程为
deferred
. 然后,您必须在没有特定实现的情况下定义其签名(接口) . 必须将包含deferred
过程的类型声明为abstract
. 这些类型无法实例化 . 所有扩展类型必须为给定的过程提供实现,除非它们本身是abstract
.为了在扩展类型中为
deferred
过程提供实现,您只需在扩展类型中声明过程并为其提供实现 .您无法将给定类型的公共过程转换为扩展类型的
generic
. 但是,您可以在基本类型中定义generic
并在其派生类型中对其进行扩展 .pass
属性默认设置,因此过程的第一个参数将是类型实例 . 但是,您可以指定它以使其更明确 . 此外,您可以使用PASS(ARGNAME)
形式指定,哪个参数(ARGNAME
)应该是实例 . 这个论点不一定是程序中的第一个 .下面是一个包含自我的示例,其中应包含您要求的所有功能: