Understanding Fortran extends types and override

╄→尐↘猪︶ㄣ 提交于 2019-12-02 23:08:07

First some comments/answers to your questions:

  • You can declare a type bound procedure being deferred. Then you have to define its signature (interface) only without a specific implementation. The type containing the deferred procedure must be declared abstract. Such types can not be instantiated. All extending types must provide an implementation for the given procedure, unless they are themselves abstract.

  • In order to provide an implementation for a deferred procedure in an extending type, you just declare the procedure in the extending type and provide an implementation for it.

  • You can not turn a public procedure of a given type into a generic in an extending type. You can, however, define a generic already in the base type and extend it in its derived types.

  • The pass attribute is set by default, so that the first argument of the procedure will be the type instance. You can, however, specify it to make it more explicit. Additionally, you could use it in the form PASS(ARGNAME) to specify, which argument (ARGNAME) should be the instance. This argument needs not be the first one in the procedure.

Below you find a self containing example, which should contain all the features you asked for:

module basis_module
  implicit none

  type, abstract :: Basis
    integer :: NBasis
  contains
    procedure(allocBasisR1Interface), deferred :: allocateBasisR1
    generic :: allocateBasis => allocateBasisR1
  end type Basis

  interface 
    ! Interface for real basis allocation
    subroutine allocBasisR1Interface(self, array)
      import
      class(Basis), intent(inout) :: self
      real, intent(in) :: array(:)
    end subroutine allocBasisR1Interface
  end interface

end module basis_module


module extension_module
  use basis_module
  implicit none

  type, extends(Basis) :: GridBasis
  contains
    ! Extending the mapping allocateBasis => allocateBasisR1 of
    ! the parent type.
    generic :: allocateBasis => allocateBasisC1
    procedure :: allocateBasisC1
    ! Implementation for the deferred procedure in Basis
    procedure :: allocateBasisR1
  end type GridBasis

contains

  subroutine allocateBasisR1(self, array)
    class(GridBasis), intent(inout) :: self
    real, intent(in) :: array(:)

    self%NBasis = size(array)
    print *, "GridBasis:allocateBasisR1"

  end subroutine allocateBasisR1


  subroutine allocateBasisC1(self, array)
    class(GridBasis), intent(inout) :: self
    complex, intent(in) :: array(:)

    self%NBasis = size(array)
    print *, "GridBasis:allocateBasisC1"

  end subroutine allocateBasisC1

end module extension_module


program test
  use extension_module
  implicit none

  type(GridBasis) :: mybasis
  real :: myRealArray(10)
  complex :: myComplexArray(5)

  call mybasis%allocateBasis(myRealArray)
  call mybasis%allocateBasis(myComplexArray)

end program test
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!