【Fortran学習|初心者向け】Fortranのクラス引数活用術:多態性(ポリモーフィズム)でコードをスマートに

1. 導入:なぜ「クラス引数」が重要なのか

数値計算のプログラムを書いていると、「円や四角形など、異なる形状の面積を一つの関数で計算したい」といった場面に遭遇します。もし形状ごとに別々の関数を作ると、管理が大変ですよね。ここで登場するのがクラス引数(多態的引数)です。これを使うことで、共通の性質を持つ複数の型を一つの引数で受け取れるようになり、コードの重複を劇的に減らすことができます。

2. 基礎知識:クラス引数とは?

Fortranにおいて、TYPEで定義された型は固定的なものですが、CLASSを使うと、その型を継承した「派生型」も受け入れ可能になります。これを専門用語で「多態性(ポリモーフィズム)」と呼びます。実行時にオブジェクトが「何者であるか」をプログラムが判断し、それぞれの型に合わせて適切な処理を行う仕組みです。

3. 実装・解決策:基底型と派生型の関係

解決策は、まず「基底型(親)」を定義し、それを継承した「派生型(子)」を作ることです。計算用のサブルーチンには引数の型としてCLASSを指定します。こうすることで、親の型を継承していれば、どのような子オブジェクトでも同じインターフェースで処理できるようになります。

4. サンプルプログラム

以下のコードは、円と長方形の面積を計算する簡単な例です。コピーしてコンパイル(gfortranなど)し、実行してみてください。

module geometry_mod
  implicit none

  ! 基底型:面積を計算するインターフェースを持つ
  type, abstract :: shape
  contains
    procedure(area_interface), deferred :: get_area
  end type

  abstract interface
    function area_interface(this) result(res)
      import :: shape
      class(shape), intent(in) :: this
      real :: res
    end function
  end interface

  ! 派生型:円
  type, extends(shape) :: circle
    real :: radius
  contains
    procedure :: get_area => circle_area
  end type

  ! 派生型:長方形
  type, extends(shape) :: rectangle
    real :: width, height
  contains
    procedure :: get_area => rect_area
  end type

contains

  function circle_area(this) result(res)
    class(circle), intent(in) :: this
    res = 3.14  this%radius2
  end function

  function rect_area(this) result(res)
    class(rectangle), intent(in) :: this
    res = this%width  this%height
  end function

  ! 多態的なサブルーチン:ここがポイント!
  ! class(shape)とすることで、円も長方形も受け取れる
  subroutine print_area(obj)
    class(shape), intent(in) :: obj
    print , "面積は:", obj%get_area()
  end subroutine
end module

program main
  use geometry_mod
  type(circle) :: my_circle
  type(rectangle) :: my_rect

  my_circle%radius = 5.0
  my_rect%width = 2.0; my_rect%height = 4.0

  ! 同じ関数で異なる型の面積を計算できる
  call print_area(my_circle)
  call print_area(my_rect)
end program

5. 応用・注意点:現場でのバグ回避

クラス引数を使う際、注意すべきは「型判定」です。受け取ったオブジェクトが特定の型であるか確認したい場合は、SELECT TYPE構文を使用しましょう。また、多態的引数は通常の引数よりも計算コストが僅かに高くなるため、極めて高い計算速度が求められる内側のループ処理などで多用しすぎないよう注意してください。まずは、プログラムの「構造設計」をすっきりさせる目的で活用するのがベストです。

コメント

タイトルとURLをコピーしました