Interfaces in Fortran
In Fortran, we can define abstract interfaces that are similar to Go’s interfaces. However, Fortran uses abstract types and type-bound procedures to achieve similar functionality. Let’s see how we can implement the geometry example in Fortran.
module geometry_module
implicit none
! Define an abstract type for geometric shapes
type, abstract :: geometry
contains
procedure(area_interface), deferred :: area
procedure(perim_interface), deferred :: perim
end type geometry
! Define the interfaces for area and perimeter
abstract interface
function area_interface(this) result(res)
import geometry
class(geometry), intent(in) :: this
real :: res
end function area_interface
function perim_interface(this) result(res)
import geometry
class(geometry), intent(in) :: this
real :: res
end function perim_interface
end interface
! Define rect type
type, extends(geometry) :: rect
real :: width, height
contains
procedure :: area => rect_area
procedure :: perim => rect_perim
end type rect
! Define circle type
type, extends(geometry) :: circle
real :: radius
contains
procedure :: area => circle_area
procedure :: perim => circle_perim
end type circle
contains
! Implement area and perimeter for rect
function rect_area(this) result(res)
class(rect), intent(in) :: this
real :: res
res = this%width * this%height
end function rect_area
function rect_perim(this) result(res)
class(rect), intent(in) :: this
real :: res
res = 2 * (this%width + this%height)
end function rect_perim
! Implement area and perimeter for circle
function circle_area(this) result(res)
class(circle), intent(in) :: this
real :: res
real, parameter :: pi = 3.14159265359
res = pi * this%radius**2
end function circle_area
function circle_perim(this) result(res)
class(circle), intent(in) :: this
real :: res
real, parameter :: pi = 3.14159265359
res = 2 * pi * this%radius
end function circle_perim
! Generic measure subroutine
subroutine measure(g)
class(geometry), intent(in) :: g
print *, "Area:", g%area()
print *, "Perimeter:", g%perim()
end subroutine measure
end module geometry_module
program main
use geometry_module
implicit none
type(rect) :: r
type(circle) :: c
r = rect(width=3.0, height=4.0)
c = circle(radius=5.0)
print *, "Rectangle:"
call measure(r)
print *, "Circle:"
call measure(c)
end program main
In this Fortran implementation:
We define an abstract type
geometry
with deferred proceduresarea
andperim
.We create concrete types
rect
andcircle
that extend thegeometry
type and implement the required procedures.The
measure
subroutine takes ageometry
class argument, allowing it to work with any type that extendsgeometry
.In the main program, we create instances of
rect
andcircle
and pass them to themeasure
subroutine.
To compile and run this Fortran program:
$ gfortran -o geometry geometry.f90
$ ./geometry
This will output the area and perimeter of the rectangle and circle.
While Fortran doesn’t have interfaces in the same way as Go, abstract types and type-bound procedures provide similar functionality, allowing for polymorphic behavior and code reuse.