Juliaでは抽象型(Abstract type)というものがあり、これを使うとオブジェクト指向プログラミングでのクラスに似た感じのコーディングができます。具体的にはc++の抽象クラスでの純粋仮想関数みたいになります。
バージョン
Julia 1.6.2
Abstract type
抽象型(Abstract type)を使うには例えば、
module Mysupermodule
export Mysuperstruct
abstract type Mysuperstruct end
function add(A::T,B::T) where T <: Mysuperstruct
error("add is not implemented for $(typeof(A))")
return
end
end
のようなmoduleを作成します。ここで、Mysuperstruct
にはadd
という関数が定義されていますが、これが呼び出されるとerrorで落ちるようにしておきます。
次に、このtypeをsuper typeにもつtypeを
module Mymodule
import ..Mysupermodule:Mysuperstruct,add
struct Mystruct <: Mysuperstruct
a::Float64
end
function add(A::T,B::T) where T <: Mystruct
return Mystruct(A.a+B.a)
end
end
と定義します。このようにしておくと、
module Testmodule
import ..Mysupermodule:Mysuperstruct,add
import ..Mymodule:Mystruct
export test
function test()
A = Mystruct(2.0)
B = Mystruct(10.0)
C = add(A,B)
println(C.a)
end
end
using .Testmodule
test()
とした時に、Mystruct
で定義されているadd
が呼び出されます。ここで、import
しているのがMysupermodule
のadd
であることに注意してください。Mystruct
で動作するadd
はTestmodule
から呼び出していません。つまり、Mysupermodule
の中にadd
が追加されています。Mysupermodule
でできることが増えているわけですね。
もし、add
が定義されていないモジュールがあったとすると、
module Hismodule
import ..Mysupermodule:Mysuperstruct,add
struct Hisstruct <: Mysuperstruct
a::Float64
end
end
module Testmodule
import ..Mysupermodule:Mysuperstruct,add
import ..Mymodule:Mystruct
import ..Hismodule:Hisstruct
export test
function test()
A = Mystruct(2.0)
B = Mystruct(10.0)
C = add(A,B)
println(C.a)
A = Hisstruct(2.0)
B = Hisstruct(10.0)
C = add(A,B)
println(C.a)
end
end
を実行した結果は
12.0
ERROR: LoadError: add is not implemented for Main.Hismodule.Hisstruct
となり、addが実装されていない方はエラーで落ちます。
これは、C++での抽象クラスにvirtualを使って定義する「純粋仮想関数」と似た感じです。もう少し似せるならば、
module Mymodule
import ..Mysupermodule:Mysuperstruct,add
struct Mystruct <: Mysuperstruct
a::Float64
end
add() = nothing
end
とすると、
ERROR: LoadError: MethodError: no method matching add(::Main.Hismodule.Hisstruct, ::Main.Hismodule.Hisstruct)
となります。どちらがいいかはお好みです。
ここではimportを使って書いていますが、usingを使っても同様の結果になるようです。