Type is(extended from abstract)

Hi,

I have a sample following code in which I am trying to test whether a certain object is extended from an abstract derived type.

Here is the module:

module my_module
  implicit none

  ! Abstract parent type
  type, abstract :: abstract_parent
    integer :: common_member
  end type abstract_parent

  ! Derived type
  type, extends(abstract_parent) :: derived_type
    real :: additional_member
  end type derived_type

  ! Derived type
  type, abstract, extends(abstract_parent) :: special_type
    real :: special_member
 end type special_type

  type, extends(special_type) :: special_derived_type
     real :: additional_member
  end type special_derived_type

end module my_module

Here is the program:

program main
  use my_module
  
  type(derived_type) :: obj1
  type(special_derived_type) :: obj2
  
  select type(obj2)
  type is(special_type)
     write(*,*) "found a special derived type"
  end select
  
end program main

I get an error during compilation with gfortran 13.2.0

33 | type is(special_type)
   |        1
Error: Derived type ‘special_type’ at (1) may not be ABSTRACT

I just wanted to check, is there any way to do this (hopefully without sending them to interface procedure rules)? Or is it not easily possible to check what types a variable extends from?

Thanks in advance for any help you can offer.

Kind regards

Perhaps this post might be useful.

1 Like

Try

   ..
   class is ( special_type )

Thank you, @alozada. I will check out the video when I get the chance this weekend. :slight_smile:

Thanks, @FortranFan. That does exactly what I need. :slight_smile:

(A note mostly for my future self). This did not work immediately on my example. It works exactly how I want as long as the initial objects are set up as allocatable classes of the abstract type and then later initialised/allocated with their respective derived types.

@nedanator , have you reviewed any material on the object-oriented aspects of Fortran, say in a reference book such as Modern Fortran Explained covering Fortran 2018? If you have not, I suggest doing so first.

This manual page may also be useful:

I think the “selector” item (the argument in select type (...)) must be polymorphic (= declared with class), rather than a variable of concrete type declared with type (which we already know its concrete type in that routine!).

Just for fun, it may be interesting to play with this kind of routine by commenting or uncommenting some blocks in select type, or changing the order of blocks, etc, etc.

module my_module2
    use my_module
    implicit none
contains

subroutine check_type( x )
    class(*), intent(in) :: x

    select type ( x )
        type is ( derived_type )
            print *, "concrete type of x = derived_type"

        !! type is ( special_derived_type )
        !!    print *, "concrete type of x = special_derived_type"

        class is ( abstract_parent )
            print *, "concrete type of x <= abstract_parent"

        class is ( special_type )
            print *, "concrete type of x <= special_type"

        class default; print *, "no match!!"
    end select
end subroutine

end module

program main
    use my_module2
    implicit none
    type(derived_type) :: d
    type(special_derived_type) :: sd

    call check_type( d )
    call check_type( sd )
end
1 Like

Hi @FortranFan. No, not really. I’ve been using and implementing object-oriented things in Fortran for about the past two months (and derived types for around 5 years) and, in that time, I have been reading documentation such as this website and other references like Intel’s webpages when I can find time. I’ve always had trouble with learning things from reading books, I find that I much more need to apply things to a project/task I am interested/passionate in to absorb the information. However, I will see if I can buy the book you recommend and will try and learn from it. Thank you for the recommendation, I greatly appreciate it. :slightly_smiling_face:

Is this the book you are referring to: “Modern Fortran Explained: Incorporating Fortran 2018 (Numerical Mathematics and Scientific Computation)” by Michael Metcalf?

Thanks a lot @septc, that’s been pretty nifty to play with and see how things change accordingly when different blocks are commented out. :slightly_smiling_face:

@nedanator ,

The section on object-oriented programming and the preceding (and related) section on procedure pointers are only about 35 pages and they can be a very quick read.

The suggestion to review that book, which is authored more as a reference, is not meant as a substitute for the coding exercises and trying things out with a project/task in mind, as you are doing rightly. Rather, it is so that you can ground yourself reasonably well with a good overview of the syntax and semantics of the language that will then give you far more informed direction toward your exercises.

Note there are aspects to modern Fortran which are not intuitive, moreover compilers vary greatly in their robustness. This makes a book such as Modern Fortran Explained a handy reference.

Thanks again for your thorough answer, @FortranFan. :slightly_smiling_face: Seems like I definitely need to get my hands on it to help with me developing my Fortran skills. Grounding myself in good practices and having a good understanding of the syntax would definitely help prevent me from falling into bad habits or any pitfalls.

Yeah, there are some aspects that don’t, at first, make sense for object-oriented things in Fortran, and the compilers definitely seem extremely variable in what they support (as also seems regularly mentioned on this discourse).

Toward this, you may want to look again at this site:

and review closely the book by Clerman and Spector listed under In Print.