I wrote the following code where an abstract type (shape_t) could be extended to a segment, a rectangle or a box. There are two procedures, one to initialize the variable and the other to print the size.
This code gave the expected result.
A segment, a rectangle or a box could be initialized and the size could be printed.
module myModule
implicit none
type, abstract :: shape_t
contains
procedure(abstract_init), deferred :: 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 :: init => init_line
procedure :: print_size => print_linesize
end type line_t
type, extends(shape_t) :: rectangle_t
real :: length,width
contains
procedure :: init => init_rectangle
procedure :: print_size => print_rectanglesize
end type rectangle_t
type, extends(shape_t) :: box_t
real :: length,width,height
contains
procedure :: init => init_box
procedure :: print_size => print_boxsize
end type box_t
contains
subroutine init_line(this,length1,length2,length3)
class(line_t), intent(inout) :: this
real, intent(in) :: length1,length2,length3
this%length = 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
this%length = length1
this%width = length2
end subroutine init_rectangle
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(line_t), allocatable :: segment
class(rectangle_t), allocatable :: rectangle
class(box_t), allocatable :: box
allocate(line_t::segment)
call segment%init(12.0,0.0,0.0)
call segment%print_size()
allocate(rectangle_t::rectangle)
call rectangle%init(12.0,5.0,0.0)
call rectangle%print_size()
allocate(box_t::box)
call box%init(12.0,5.0,2.0)
call box%print_size()
end program main
But as there are no the same number of dimensions between segment, rectangle and box and I do not know how to overload a procedure in a abstract interface, I use 3 real parameters to initialise variables (even for segment and rectangle where only one or two are needed, respectively).
I wonder how is it possible to modify this code, to change in the main program :
call segment%init(12.0,0.0,0.0) and call rectangle%init(12.0,5.0,0.0) to call segment%init(12.0) and call rectangle%init(12.0,5.0)
Thanks for answer.