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 class argument this requires the attribute intent(inout).

The instantiation of an object is simply done by variable declaration. Classes in Fortran 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.

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

    ! The animal class.
    type, public :: animal_class
        integer, public :: age
        real,    public :: size
    contains
        procedure, public  :: print_age => animal_print_age
    end type animal_class
contains
    subroutine animal_print_age(this)
        !! Prints the animal's age to stdout.
        class(animal_class), intent(inout) :: this
        print '("I am ", i0, " year(s) old")', this%age
    end subroutine animal_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 => dog_bark
    end type dog_class
contains
    subroutine dog_bark(this)
        !! Barks to stdout.
        class(dog_class), intent(inout) :: this
        print '("woof")'
    end subroutine dog_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 => duck_quack
    end type duck_class
contains
    subroutine duck_quack(this)
        !! Quacks to stdout.
        class(duck_class), intent(inout) :: this
        print '("quack")'
    end subroutine duck_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:

$ gfortran13 -c classes.f90
$ gfortran13 -o main main.f90 classes.o
$ ./main
woof
I am 6 year(s) old
quack
I am 2 year(s) old