Object-Oriented Programming

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

Classes

Classes in Fortran are just plain type structures that contain attributes and methods. The functions and subroutines of a class have to be listed under contains. The visibility of each method can be set to either public or private. The first argument of a class method has to be a reference to the object itself, using the class type, and named this by convenience, although any other name is permitted. The this argument requires an attribute intent(in out).

The instantiation of an object is done by simple variable declaration. Classes in Fortran do not feature intrinsic constructors, but one can simply write a subroutine initialise() or similar to achieve the same behaviour.

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

! classes.f90
module animal_mod
! The animal module.
    implicit none
    private

    ! The animal class.
    type, public :: animal_class
        integer :: age
        real    :: size
        contains
            procedure, public  :: print_age
    end type animal_class

    contains
        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
end module animal_mod

module dog_mod
! The dog module.
    use :: animal_mod
    implicit none
    private

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

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

module duck_mod
! The duck module.
    use :: animal_mod
    implicit none
    private

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

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

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

! main.f90
program main
    use :: animal_mod
    use :: dog_mod
    use :: duck_mod
    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 and run the example with:

$ gfortran7 -c classes.f90
$ gfortran7 -Wl,-rpath=/usr/local/lib/gcc7/ -o main main.f90 classes.o
$ ./main
woof
6
quack
2