Clicky

Fortran Wiki
Object-oriented programming (changes)

Skip the Navigation Links | Home Page | All Pages | Recently Revised | Authors | Feeds | Export |

Showing changes from revision #27 to #28: (追記) Added (追記ここまで) | (削除) Removed (削除ここまで) | (削除) Chan (削除ここまで)(追記) ged (追記ここまで)

Pseudo Object Oriented Style in Fortran 90

Derived types

In object-oriented languages such as C++, one can define classes that contain both data and methods which operate on that data. One can then create separate instances of the class, each with its own data. A method called from an instance of the class will work on the data held by that particular instance.

In Fortran, modules may contain data, but there is no notion of separate instances of a module. In order to obtain class-like behavior, one can combine a module, which contains the methods that operate on the class, with a derived type containing the data. There can be separate "instances" of the type in that we can allocate many variables of that type which can be passed as parameters to the methods contained in the module.

To illustrate these points consider a simple Circle class, based on an example in Akin (2003, p. 34):

module class_Circle
 implicit none
 private
 public :: Circle, circle_area, circle_print
 real :: pi = 3.1415926535897931d0 ! Class-wide private constant
 type Circle
 real :: radius
 end type Circle
contains
 function circle_area(this) result(area)
 type(Circle), intent(in) :: this
 real :: area
 area = pi * this%radius**2
 end function circle_area
 subroutine circle_print(this)
 type(Circle), intent(in) :: this
 real :: area
 area = circle_area(this) ! Call the circle_area function
 print *, 'Circle: r = ', this%radius, ' area = ', area
 end subroutine circle_print
end module class_Circle
program circle_test
 use class_Circle
 implicit none
 type(Circle) :: c ! Declare a variable of type Circle.
 c = Circle(1.5) ! Use the implicit constructor, radius = 1.5.
 call circle_print(c) ! Call a class subroutine
end program circle_test

NOTE: circle_print and circle_area could be made accessible through generic procedure names print and area, respectively. That gets closer to a standard OOP language, because print can be defined for multiple "sub-classed" objects.

Run-Time Polymorphism


Object-Oriented Features of Fortran 2003

Type-bound procedures

New features in Fortran 2003 allow us to improve upon the object-oriented approach above by using type-bound procedures which allow us to write

a = c%area
call c%print

instead of the more verbose

a = circle_area(c)
call circle_print(c)

If the above example is modified to provide print and area as generic interfaces, it is more concise, even though it does not follow modern OOP syntax:

a = area(c)
call print(c)

The program above, modified to use type-bound procedures, looks like this

module class_Circle
 implicit none
 private
 real :: pi = 3.1415926535897931d0 ! Class-wide private constant
 type, public :: Circle
 real :: radius
 contains
 procedure :: area => circle_area
 procedure :: print => circle_print
 end type Circle
contains
 function circle_area(this) result(area)
 class(Circle), intent(in) :: this
 real :: area
 area = pi * this%radius**2
 end function circle_area
 subroutine circle_print(this)
 class(Circle), intent(in) :: this
 real :: area
 area = this%area() ! Call the type-bound function
 print *, 'Circle: r = ', this%radius, ' area = ', area
 end subroutine circle_print
end module class_Circle
program circle_test
 use class_Circle
 implicit none
 type(Circle) :: c ! Declare a variable of type Circle.
 c = Circle(1.5) ! Use the implicit constructor, radius = 1.5.
 call c%print ! Call the type-bound subroutine
end program circle_test

Note that we have changed the dummy parameters from type(Circle) to class(Circle). We can then call the class functions in an object-oriented fashion as a = c%area and call c%print, where the type is passed to the first argument of the functions circle_area and circle_print automatically. See Metcalf, Reid, and Cohen (2004, p. 279) for additional information.


See Also

References

Revised on January 19, 2024 17:29:08 by Beliavsky? (173.48.128.134) (8354 characters / 3.0 pages)
Edit | Back in time (27 revisions) | Hide changes | History | Views: Print | TeX | Source | Linked from: HomePage, Fortran 2003, Fortran Wiki discussion, Forpedo, Stats, hash table example, Design Patterns, Guide to Fortran 2008 Programming, Modern Fortran Explained

AltStyle によって変換されたページ (->オリジナル) /