Object-Oriented Programming

With Fortran 2003, object-oriented programming has been added to the language standard.


Classes in Fortran are just plain type structures that contain attributes and methods. The class functions and subroutines have to be listed under contains, to be recognised as methods.

The first argument of each method has to be of the specific class type and named this by convenience, although any other name is permitted. The intent of the this argument is always in out to allow altering of attributes.

The instantiation of objects is done by variable declarations. Classes do not feature intrinsic constructors, but one can simply write a subroutine init() or similar to achieve the same behaviour.

It is recommended to use a distinct module for each class.

! animals.f90
module animals
    implicit none

    ! The generic animal class.
    type, public :: animal_class
        integer :: age
            procedure, public :: print_age
    end type animal_class

    ! The dog class.
    type, public, extends(animal_class) :: dog_class
            procedure, public :: bark
    end type dog_class

    ! The duck class.
    type, public, extends(animal_class) :: duck_class
            procedure, public :: quack
    end type duck_class

        subroutine print_age(this)
            !! Prints the animal's age to stdout.
            implicit none
            class(animal_class), intent(in out) :: this
            print '(i0)', this%age
        end subroutine print_age

        subroutine bark(this)
            !! Barks to stdout.
            implicit none
            class(dog_class), intent(in out) :: this
            print '(a)', 'woof'
        end subroutine bark

        subroutine quack(this)
            !! Quacks to stdout.
            implicit none
            class(duck_class), intent(in out) :: this
            print '(a)', 'quack'
        end subroutine quack
end module animals

The following program creates objects of dog_class and duck_class and calls their methods:

! main.f90
program main
    use :: animals
    implicit none
    type(dog_class)  :: dog
    type(duck_class) :: duck

    dog%age  = 6
    duck%age = 2

    call dog%bark()
    call dog%print_age()

    call duck%quack()
    call duck%print_age()
end program main

Compile the example with:

$ gfortran7 -c animals.f90
$ gfortran7 -Wl,-rpath=/usr/local/lib/gcc7/ -o animals main.f90 animals.o
$ ./animals