100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Object-Oriented Fortran

Explore how modern Fortran supports encapsulation, inheritance via type extension, and runtime polymorphism through CLASS and SELECT TYPE.

Modern FortranAdvanced11 min readJul 10, 2026
Analogies

OOP Arrives in Fortran 2003

Fortran 2003 added type extension, type-bound procedures, and polymorphism to the derived-type system, letting programs express object-oriented designs without abandoning Fortran's array-oriented performance strengths. A base type declares TYPE :: shape with a CONTAINS section binding a procedure like area, and any type extending it, TYPE, EXTENDS(shape) :: circle, inherits shape's components and procedures while adding its own (radius) and optionally overriding area with its own circle-specific implementation, following the same is-a relationship familiar from languages like C++ or Java.

🏏

Cricket analogy: A base TYPE :: shape extended by circle and rectangle is like a base 'Cricketer' role extended by 'Batter' and 'Bowler' specializations, each inheriting shared attributes like team and jersey number while adding their own specific stats.

Building an Inheritance Hierarchy

Extended types automatically inherit every component and type-bound procedure of their parent, and can override an inherited procedure by redeclaring the same binding name with a new implementation, as long as the interface is type-compatible. The parent's components remain accessible in the child, and a child instance can be treated as a value of the parent type in contexts requiring a CLASS(shape) argument, which is the essence of Liskov-substitutability that makes polymorphic collections of shapes work correctly regardless of which concrete extension each element actually is.

🏏

Cricket analogy: A Batter type inheriting jerseyNumber from Cricketer and overriding a play() method is like Rohit Sharma inheriting general team-player attributes while his specific batting technique overrides a generic play style.

Polymorphism With CLASS and SELECT TYPE

Declaring a variable as CLASS(shape), rather than TYPE(shape), makes it polymorphic: it can hold any extension of shape at runtime, and calling s%area() dispatches dynamically to whichever concrete type's implementation is actually stored, exactly like virtual dispatch in C++. When you need to act on type-specific components not present in the base type, SELECT TYPE (s) constructs a runtime type-selection block with TYPE IS (circle) and TYPE IS (rectangle) branches, letting you safely downcast and access circle-specific components like radius only within the branch where the runtime type has been confirmed to match.

🏏

Cricket analogy: CLASS(shape) dynamically dispatching to circle%area() or rectangle%area() is like a scorer calling player.play() on a generic 'player' slot that resolves at runtime to Bumrah's bowling action or Kohli's batting stroke depending on who's actually at the crease.

Abstract Types and Deferred Bindings

An ABSTRACT type, declared TYPE, ABSTRACT :: shape, cannot be instantiated directly and typically pairs a DEFERRED type-bound procedure, PROCEDURE(area_interface), DEFERRED :: area, with an abstract interface declaring only the signature; every concrete extension must supply its own implementation of that deferred binding or itself remain abstract. This mirrors an abstract base class or pure virtual function in C++, enforcing at compile time that no one can create a bare, meaningless 'shape' object and forcing every concrete shape to define what area() actually means for it.

🏏

Cricket analogy: An ABSTRACT :: shape type is like the generic notion of 'Player' being unselectable on its own in a fantasy cricket app; you must pick a concrete Batter or Bowler, each required to define its own scoring formula.

Fortran's polymorphism is opt-in: a plain TYPE(shape) variable is monomorphic and can only ever hold a shape, while CLASS(shape) is polymorphic and can hold shape or any of its extensions. Always choose CLASS(...) for dummy arguments and function results when you want dynamic dispatch across a type hierarchy.

Attempting to declare a variable of an ABSTRACT type directly, e.g. TYPE(shape) :: s where shape is ABSTRACT, is a compile-time error. You must either use CLASS(shape) polymorphically with a concrete extension assigned at runtime, or instantiate a concrete extension like TYPE(circle) directly.

  • Fortran 2003 introduced type extension, type-bound procedures, and polymorphism for object-oriented design.
  • TYPE, EXTENDS(parent) :: child inherits the parent's components and type-bound procedures, and can override them.
  • CLASS(shape) declares a polymorphic variable that can hold shape or any extension, enabling dynamic dispatch.
  • SELECT TYPE with TYPE IS (...) branches lets you safely downcast to access type-specific components.
  • ABSTRACT types cannot be instantiated directly and typically declare DEFERRED type-bound procedures.
  • Every concrete extension of an abstract type must implement its DEFERRED bindings or remain abstract itself.
  • TYPE(x) is monomorphic; CLASS(x) is polymorphic — choose CLASS for arguments needing dynamic dispatch.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#FortranStudyNotes#ObjectOrientedFortran#Object#Oriented#Fortran#OOP#StudyNotes#SkillVeris#ExamPrep