Help us understand the problem. What is going on with this article?

続・fortranでもオブジェクト指向したい!「継承と抽象クラス」

More than 1 year has passed since last update.

前回: https://qiita.com/Bluepost59/items/ca560c49a8c19484db9d

果てしなく間が空いてしまったが、今回は一歩進んで継承と抽象クラスについてまとめたいと思う。

※「そもそも抽象クラスって何」って人はこれを見て下さい
https://qiita.com/Bluepost59/items/eef6f48fdd322b0b9791

継承

継承は簡単で、typeの後にextendsキーワードをつけるだけでよい。

type,extends(parent_class) :: child_class
   integer param1
   !...
contains
   procedure :: method1 => child_method1
   !...
end type child_class

抽象クラス

抽象クラス自体はtypeにabstract属性を付けるだけでよい。

関数やサブルーチンをつけるところがかなりややこしい。procedure文だけでは不十分で、interface文で引数や戻り値を設定する必要がある。

type,abstract :: absclass
   integer param2
   !...
contains
   procedure(absmethod1),deferred :: method1
   procedure(absmethod2),deferred :: method2
   !...
end type absclass

!引用仕様(戻り値、引数)の定義
interface
   subroutine absmethod1(self,subparam)
      import absclass
      class(absclass) self
      integer subparam
   end subroutine absmethod1

   double precision function absmethod2(self,subparam)
      import absclass
      !...
   end function absmethod2
end interface

ポイントはクラス本体の宣言と引用仕様の宣言が相互参照のようになっているところだ。はっきりいって謎な仕様ではある。

何はともあれ、これで抽象クラスが定義された。この子クラスではmethodをオーバーライドしなければコンパイルエラーとなる。

具体例

抽象クラスgirlと、それを継承したクラスidolを実装した。girlはnameおよびそのセッタとゲッタ、idolはそれに加えてgroupとセッタ、ゲッタを実装してある。

mod_idol.f90
module mod_idol
  implicit none

!---------------------------------------------------
! 抽象クラス girl
  type,abstract :: girl
     private
     character(len=60) :: name = "noname"
   contains
     procedure(girl_set_name),deferred :: set_name
     procedure(girl_get_name),deferred :: get_name
  end type girl

! 引用仕様の宣言
  interface
     subroutine girl_set_name(self,str)
       import girl
       class(girl) self
       character(len=60) str
     end subroutine girl_set_name

     character(len=60) function girl_get_name(self)
       import girl
       class(girl) self
     end function girl_get_name
  end interface
!---------------------------------------------------
! クラス idolの宣言部 
  type,extends(girl) :: idol
     private
     character(len=60) group
   contains
     procedure :: set_name => idol_set_name
     procedure :: get_name => idol_get_name
     procedure :: join => idol_join
     procedure :: get_group => idol_get_group
  end type idol

contains
!---------------------------------------------------
! クラス idolの実装部
  subroutine idol_set_name(self,str)
    class(idol) self
    character(len=60) str
    self%name = str
  end subroutine idol_set_name

  character(len=60) function idol_get_name(self)
    class(idol) self
    idol_get_name = trim(self%name)
  end function idol_get_name

  subroutine idol_join(self,group)
    class(idol) self
    character(len=60) group
    self%group = group
  end subroutine idol_join

  character(len=60) function idol_get_group(self)
    class(idol) self
    idol_get_group = trim(self%group)
  end function idol_get_group

end module mod_idol
main.f90
program main
  use mod_idol
  implicit none

  type(idol) :: myidol

  character(len=60) :: myname = "Momoka"
  character(len=60) :: myunit = "momo_pear_berry"

  call myidol%set_name(myname)
  call myidol%join(myunit)

  write(6,*) "name:", myidol%get_name()
  write(6,*) "unit:", myidol%get_group()

end program main

gist: https://gist.github.com/Bluepost59/be1975d070e3451c0aa51ab4d6d160f5

感想

  • コードがえげつなく長くなってしまった。もう少し短く書けないものか。
  • とはいえ古文と揶揄されるfortranでもOOPが一通り実装できたので満足。
  • 正直C++の方が楽

参考サイト

NAG
http://www.nag-j.co.jp/nagfor/np52_manual/np52_manual_10_2.html

IBM
https://www.ibm.com/support/knowledgecenter/ja/SSGH4D_15.1.0/com.ibm.xlf151.aix.doc/language_ref/abstracttypes.html

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした