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(inout).

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(inout) :: this
        print '(a, i0, a)', 'I am ', this%age, ' year(s) old'
    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(inout) :: 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(inout) :: 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:

$ gfortran8 -c classes.f90
$ gfortran8 -Wl,-rpath=/usr/local/lib/gcc8/ -o main main.f90 classes.o
$ ./main
woof
I am 6 year(s) old
quack
I am 2 year(s) old