Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Invoke ancester's method of the same name while overriding

Blane_J_
New Contributor I
376 Views

Here's the sample:

module mod1
    implicit none
    
    type, abstract :: tp1
        private
        character(5) :: var1 = "abcde"
    contains
        private
        procedure, public, pass :: sub1
    end type tp1
    
    contains

    subroutine sub1(this)
        implicit none
        
        class(tp1), intent(in) :: this

        print*, this % var1
        
    end subroutine sub1
    
end module mod1

module mod2
    use mod1, only: tp1
    implicit none

    type, extends(tp1) :: tp2
        private
        character(5) :: var2 = "12345"
    contains
        private
        procedure, public, pass :: sub1
    end type tp2
    
    contains

    subroutine sub1(this)
        implicit none
        
        class(tp2), intent(in) :: this

        !--------------
        ! Is it possible to invoke sub1 of ancestor tp1 here and how to do that ?
        !--------------

        print*, this % var2
        
    end subroutine sub1
    
end module mod2

So is it possilbe that procedure sub1 of the child class tp2 invoke ancester's sub1 while override it ? Thanks for any help.

0 Kudos
4 Replies
DavidWhite
Valued Contributor II
376 Views

Two issues, I think:

1. sub1 of the ancestor is not visible

2. can't have two routines of same name.

I think in mod2, the use statement for mod1 needs to include sub1, with the rename option to give it a new name to use within mod2

0 Kudos
Blane_J_
New Contributor I
376 Views

Thanks David. I think it is more convenient to use type-bound procedure rather than invoke it directly: sub1 of the ancestor impliments part of the job and in decendent, we inherit the first part and accomplish the remaining part in addition.

In C# there is a key word "base" which is used to invoke ancestor's public method directly within decendent, here in Fortran I wonder if there's any way to impliment the same functionality. 

0 Kudos
FortranFan
Honored Contributor II
376 Views

Blane J. wrote:

Thanks David. I think it is more convenient to use type-bound procedure rather than invoke it directly: sub1 of the ancestor impliments part of the job and in decendent, we inherit the first part and accomplish the remaining part in addition.

In C# there is a key word "base" which is used to invoke ancestor's public method directly within decendent, here in Fortran I wonder if there's any way to impliment the same functionality. 

@Blane J.,

In Fortran, an object instance of an extension type (say e) can reference the type it extends (say b) by the type name e.g., ..%b.. but not when the base type is ABSTRACT.  However the components and procedure bindings of the base ABSTRACT type can be referenced directly (notwithstanding any considerations of PRIVATE/PUBLIC attributes with visibility in a given scope).

Given what you show in the original post, an option you may to consider is generic bindings for your 'sub' and think of ways you can relate to such bindings when it comes to disambiguation, say for example add a 'dummy' dummy argument to.the 'sub' binding in the base ABSTRACT type named 'base' which does your 'part of the job' when the value is true!

module mod1
   implicit none

   type, abstract :: tp1
      private
      character(5) :: var1 = "abcde"
   contains
      private
      procedure, pass :: sub1
      generic, public :: sub => sub1
   end type tp1

contains

   subroutine sub1(this, base)
      implicit none

      class(tp1), intent(in) :: this
      logical, intent(in) :: base

      if ( base ) then
         print*, this % var1
      else
         ! handling elided
      end if

   end subroutine sub1

end module mod1

module mod2
   use mod1, only: tp1
   implicit none

   type, extends(tp1) :: tp2
      private
      character(5) :: var2 = "12345"
   contains
      private
      procedure, pass :: sub2
      generic, public :: sub => sub2
   end type tp2

contains

   subroutine sub2(this)
      implicit none

      class(tp2), intent(in) :: this

      !--------------
      ! Is it possible to invoke sub1 of ancestor tp1 here and how to do that ?
      !--------------
      call this%sub( base=.true. )
      print*, this %var2

   end subroutine sub2

end module mod2
   use mod2, only : tp2
   type(tp2) :: foo
   call foo%sub()
end

 

0 Kudos
Blane_J_
New Contributor I
376 Views

FortranFan wrote:

In Fortran, an object instance of an extension type (say e) can reference the type it extends (say b) by the type name e.g., ..%b.. but not when the base type is ABSTRACT.  However the components and procedure bindings of the base ABSTRACT type can be referenced directly (notwithstanding any considerations of PRIVATE/PUBLIC attributes with visibility in a given scope).

So the point is about the ABSTRACT affair. The GENERIC solution is feasible and appreciate your help, FortranFan.

0 Kudos
Reply