This question follows Fortran : Is it possible to overload a procedure in a abstract interface?.
Following the second option suggested by Federico Perini in its answer, I wrote the following code where a question is asked to the user to choose between line, rectangle or box.
module myModule
implicit none
type, abstract :: shape_t
contains
! Put init in a generic interface
procedure(abstract_init), deferred, private :: shared_init
generic :: init => shared_init
procedure(abstract_print), deferred :: print_size
end type shape_t
abstract interface
subroutine abstract_init(this,length1,length2,length3)
import shape_t
class(shape_t), intent(inout) :: this
real, intent(in) :: length1,length2,length3
end subroutine abstract_init
subroutine abstract_print(this)
import shape_t
class(shape_t), intent(in) :: this
end subroutine abstract_print
end interface
type, extends(shape_t) :: line_t
real :: length
contains
procedure :: shared_init => init_line
procedure :: init_line_1d
generic :: init => init_line_1d
procedure :: print_size => print_linesize
end type line_t
type, extends(shape_t) :: rectangle_t
real :: length,width
contains
procedure :: shared_init => init_rectangle
procedure :: init_rectangle_2d
generic :: init => init_rectangle_2d
procedure :: print_size => print_rectanglesize
end type rectangle_t
type, extends(shape_t) :: box_t
real :: length,width,height
contains
procedure :: shared_init => init_box
procedure :: print_size => print_boxsize
end type box_t
contains
subroutine init_line_1d(this,length1)
class(line_t), intent(inout) :: this
real, intent(in) :: length1
this%length = length1
end subroutine init_line_1d
subroutine init_line(this,length1,length2,length3)
class(line_t), intent(inout) :: this
real, intent(in) :: length1,length2,length3
call init_line_1d(this,length1)
end subroutine init_line
subroutine print_linesize(this)
class(line_t), intent(in) :: this
print*,'Line size',this%length,'meter'
end subroutine print_linesize
subroutine init_rectangle(this,length1,length2,length3)
class(rectangle_t), intent(inout) :: this
real, intent(in) :: length1,length2,length3
call init_rectangle_2d(this,length1,length2)
end subroutine init_rectangle
subroutine init_rectangle_2d(this,length1,length2)
class(rectangle_t), intent(inout) :: this
real, intent(in) :: length1,length2
this%length = length1
this%width = length2
end subroutine init_rectangle_2d
subroutine print_rectanglesize(this)
class(rectangle_t), intent(in) :: this
print*,'Rectangle area',this%length*this%width,'meter^2'
end subroutine print_rectanglesize
subroutine init_box(this,length1,length2,length3)
class(box_t), intent(inout) :: this
real, intent(in) :: length1,length2,length3
this%length = length1
this%width = length2
this%height = length3
end subroutine init_box
subroutine print_boxsize(this)
class(box_t), intent(in) :: this
print*,'Box volume',this%length*this%width*this%height,'meter^3'
end subroutine print_boxsize
end module myModule
program main
use myModule
implicit none
class(shape_t), allocatable :: dynamic_typing
integer :: choice
print *,'choice (1:line, 2:rectangle or 3:box)'
read(*,'(i1)') choice
select case (choice)
case(1)
allocate(line_t::dynamic_typing)
case(2)
allocate(rectangle_t::dynamic_typing)
case(3)
allocate(box_t::dynamic_typing)
case default
print *,'not permitted'
stop
end select
select type (dynamic_typing)
type is (line_t)
call dynamic_typing%init(4.0)
call dynamic_typing%print_size()
type is (rectangle_t)
call dynamic_typing%init(4.0,3.0)
call dynamic_typing%print_size()
type is (box_t)
call dynamic_typing%init(4.0,3.0,2.0)
call dynamic_typing%print_size()
end select
end program main
But I am not able to avoid the select type part. I would like to avoid it and do the stuff DIRECTLY in the select case part.
Something like that :
select case (choice)
case(1)
allocate(line_t::dynamic_typing)
call dynamic_typing%init(4.0)
call dynamic_typing%print_size()
case(2)
allocate(rectangle_t::dynamic_typing)
call dynamic_typing%init(4.0,3.0)
call dynamic_typing%print_size()
case(3)
allocate(box_t::dynamic_typing)
call dynamic_typing%init(4.0,3.0,2.0)
call dynamic_typing%print_size()
case default
print *,'not permitted'
stop
end select
Is it possible or not ?