I'm beginning with Fortran 2008 and I'm struggling with OOP greatly. It seems, that there are very few materials, which explain a very basic OOP concepts in 2008 language standard.
I've found information about inheritance, but I was unable to find any info about polymorphism.
So if I wanted to overload a function in C++, I can do it like this (example from Wikipedia):
// volume of a cube
int volume(const int s)
{
return s*s*s;
}
// volume of a cylinder
double volume(const double r, const int h)
{
return 3.1415926*r*r*static_cast<double>(h);
}
// volume of a cuboid
long volume(const long l, const int b, const int h)
{
return l*b*h;
}
But, how am I supposed to do the same thing in Fortran 2008?
The idea of overloading as given in the C++ examples has an implementation in Fortran, dating back to the generics of Fortran 90.
Given a set of specific procedures a generic identifier may be used to identify this set. In this answer I'll give a very high-level introduction to this concept. There are a lot of subtleties which may require further reading/questions to address.
Unlike the C++ example, our Fortran specific procedures need to be named separately. Let's have the two functions (third can be added mutatis mutandis)
integer function volume_cube(s)
integer, intent(in) :: s
...
end function volume_cube
double precision function volume_cylinder(r, h)
double precision, intent(in) :: r
integer, intent(in) :: h
...
end function volume_cylinder
We can then add a generic interface for something called volume
:
interface volume
procedure volume_cube, volume_cylinder
end interface
We can then reference the generic volume
and the compiler will determine which specific function to use.
There is much more to learn about generics, including what else they offer beyond this simple overloading. One should also understand how specific procedures are resolved (simple in this case, not so in others) and the restrictions on which specific procedures may be lumped together. As you use generics problematic cases are likely to have particular questions. I answer here only as I couldn't see an introductory question and I don't attempt to address the many varied difficulties or values.
Complete example
module mod
private
interface volume
module procedure volume_cube, volume_cylinder
end interface volume
public volume
contains
integer function volume_cube(s)
integer, intent(in) :: s
volume_cube = s**3
end function volume_cube
double precision function volume_cylinder(r, h)
double precision, intent(in) :: r
integer, intent(in) :: h
volume_cylinder = 3.1415926d0*r**2*h
end function volume_cylinder
end module mod
use mod
print*, volume(2), volume(2d0,4)
end