You can do it by using single dispatch twice:
Module m
Implicit None
Type, Public, Abstract :: Parent
Contains
Procedure( i_Parent_Parent ), Public , Deferred :: f
Procedure( i_Child_Parent ), Pass( bar ), Private, Deferred :: f_c_p
Procedure( i_set ), Public , Deferred :: set
End Type Parent
Type, Public, Extends( Parent ) :: Child
Integer , Private :: data
Contains
Procedure , Public :: f => f_Child_Parent
Procedure, Pass( bar ), Private :: f_c_p => f_Child_Child
Procedure , Public :: set => f_Child_set
End Type Child
Private
Abstract Interface
Subroutine i_Parent_Parent( foo, bar )
Import :: Parent
Implicit None
Class( Parent ), Intent( In ) :: foo
Class( Parent ), Intent( In ) :: bar
End Subroutine i_Parent_Parent
Subroutine i_Child_Parent( foo, bar )
Import :: Parent, Child
Implicit None
Class( Child ), Intent( In ) :: foo
Class( Parent ), Intent( In ) :: bar
End Subroutine i_Child_Parent
Subroutine i_set( foo, data )
Import :: Parent
Class( Parent ), Intent( InOut ) :: foo
Integer , Intent( In ) :: data
End Subroutine i_set
End Interface
Contains
Subroutine f_Child_Parent( foo, bar )
Implicit None
Class( Child ), Intent( In ) :: foo
Class( Parent ), Intent( In ) :: bar
Call bar%f_c_p( foo )
End Subroutine f_Child_Parent
Subroutine f_Child_Child( foo, bar )
Implicit None
Class( Child ), Intent( In ) :: foo
Class( Child ), Intent( In ) :: bar
Write( *, * ) 'In child child foo%data = ', foo%data, ' bar%data = ', bar%data
End Subroutine f_Child_Child
Subroutine f_Child_set( foo, data )
Implicit None
Class( Child ), Intent( InOut ) :: foo
Integer , Intent( In ) :: data
foo%data = data
End Subroutine f_Child_set
End Module m
Program driver
Use m, Only : Parent, Child
Class( Parent ), Allocatable :: foo, bar
Allocate( Child :: foo )
Allocate( Child :: bar )
Call foo%set( 3 )
Call bar%set( 4 )
Call foo%f( bar )
End Program driver
ian@eris:~/work/stack$ gfortran-8 -std=f2008 -fcheck=all -Wall -Wextra dd.f90
ian@eris:~/work/stack$ ./a.out
In child child foo%data = 3 bar%data = 4
ian@eris:~/work/stack$
Whether this is quicker than select type
will be implementation dependent, but I think it is cleaner.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…