Reading Metcalf/Reid/Cohen and Chapman, I was able to write my first abstract type with a deferred procedure. As said above, with abstract types one can get run-time polymorphism without the need for select type.
module person_mod
implicit none
!
type, abstract, public :: person
character (len=20) :: name
contains
procedure(display_p), deferred :: display
end type person
!
abstract interface
subroutine display_p(this)
import person
implicit none
class(person), intent(in) :: this
end subroutine display_p
end interface
!
type, extends(person) :: worker
integer :: pay
contains
procedure :: display => display_worker
end type
!
type, extends(person) :: student
integer :: grade
contains
procedure :: display => display_student
end type
character (len=*), parameter :: fmt_d = "(3a8,i8)"
!
contains
!
subroutine display_worker(this)
class(worker), intent(in) :: this
print fmt_d,"name = ",this%name," pay =",this%pay
end subroutine display_worker
!
subroutine display_student(this)
class(student), intent(in) :: this
print fmt_d,"name = ",this%name," grade =",this%grade
end subroutine display_student
!
end module person_mod
!
program test_person
use person_mod, only: person, worker, student
implicit none
type(worker) :: w
type(student) :: s
class(person), allocatable :: p
w = worker("Ed",50000)
s = student("Ann",11)
call w%display()
p = w
call p%display()
call s%display()
p = s ! p has new type
call p%display()
end program test_person
Output:
name = Ed pay = 50000
name = Ed pay = 50000
name = Ann grade = 11
name = Ann grade = 11